Skip to content

Commit c9f76a9

Browse files
committed
Resolve remaining changes after rebase
1 parent f747eae commit c9f76a9

2 files changed

Lines changed: 154 additions & 27 deletions

File tree

Cargo.lock

Lines changed: 28 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.rs

Lines changed: 126 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use pdm::app::{
99
use pdm::bitcoin_config::{
1010
parse_config as parse_bitcoin_config, save_config as save_bitcoin_config,
1111
};
12-
use pdm::p2poolv2_config::{apply_edit as apply_p2pool_edit, flatten_config};
1312
use pdm::components::settings_view::{FIELDS, FieldKind};
13+
use pdm::p2poolv2_config::{apply_edit as apply_p2pool_edit, flatten_config};
1414
use pdm::settings::{load_settings, save_settings};
1515
use pdm::ui;
1616
use std::ops::ControlFlow;
@@ -133,6 +133,38 @@ where
133133
}
134134
}
135135

136+
// P2Pool config
137+
CurrentScreen::P2PoolConfig => {
138+
if app.p2pool_conf_path.is_some() {
139+
if app.p2pool_config_view.sidebar_focused {
140+
match key.code {
141+
KeyCode::Enter => {
142+
app.p2pool_config_view.sidebar_focused = false;
143+
AppAction::None
144+
}
145+
k => sidebar_nav(k, app),
146+
}
147+
} else {
148+
// Build flat entry list and delegate to the view
149+
let entries = app
150+
.p2pool_config
151+
.as_ref()
152+
.map(|cfg| flatten_config(cfg))
153+
.unwrap_or_default();
154+
app.p2pool_config_view.handle_input(key, &entries)
155+
}
156+
} else {
157+
match key.code {
158+
KeyCode::Enter => {
159+
app.p2pool_config_view.warning_message = None;
160+
AppAction::OpenExplorer(ExplorerTrigger::P2PoolConfig)
161+
}
162+
KeyCode::Esc => AppAction::CloseModal,
163+
k => sidebar_nav(k, app),
164+
}
165+
}
166+
}
167+
136168
CurrentScreen::Settings => {
137169
if app.settings_view.sidebar_focused {
138170
match key.code {
@@ -178,13 +210,19 @@ fn bootstrap_from_settings(app: &mut App) {
178210
}
179211
}
180212

181-
// P2Pool config
182-
if let Some(path) = &app.settings.p2pool_conf_path {
183-
app.p2pool_conf_path = Some(path.clone());
184-
if let Some(p) = path.to_str()
185-
&& let Ok(cfg) = P2PoolConfig::load(p)
186-
{
187-
app.p2pool_config = Some(cfg);
213+
// P2Pool config — only set the path when the config is actually loadable
214+
if let Some(path) = &app.settings.p2pool_conf_path.clone() {
215+
if let Some(p) = path.to_str() {
216+
match P2PoolConfig::load(p) {
217+
Ok(cfg) => {
218+
app.p2pool_conf_path = Some(path.clone());
219+
app.p2pool_config = Some(cfg);
220+
}
221+
Err(e) => {
222+
eprintln!("pdm: failed to load p2pool config on startup: {e}");
223+
// Leave both as None so the view prompts the user to re-select
224+
}
225+
}
188226
}
189227
}
190228
}
@@ -228,11 +266,34 @@ fn handle_action(action: AppAction, app: &mut App) -> Result<ControlFlow<()>> {
228266
if let Some(trigger) = app.explorer_trigger.take() {
229267
match trigger {
230268
ExplorerTrigger::P2PoolConfig => {
231-
app.p2pool_conf_path = Some(path.clone());
232-
if let Some(p) = path.to_str()
233-
&& let Ok(cfg) = P2PoolConfig::load(p)
234-
{
235-
app.p2pool_config = Some(cfg);
269+
match P2PoolConfig::load(path.to_str().unwrap_or_default()) {
270+
Ok(cfg) => {
271+
// Sanity check — a valid p2pool config must have
272+
// a stratum section with at least a hostname
273+
274+
if cfg.stratum.hostname.is_empty() {
275+
app.p2pool_config_view.warning_message = Some(
276+
"Config loaded but appears invalid: stratum.hostname is empty. Select another file."
277+
.to_string(),
278+
);
279+
app.p2pool_conf_path = None;
280+
app.p2pool_config = None;
281+
} else {
282+
app.p2pool_conf_path = Some(path.clone());
283+
app.p2pool_config = Some(cfg);
284+
app.p2pool_config_view.sidebar_focused = false;
285+
app.p2pool_config_view.warning_message = None;
286+
app.p2pool_config_view.selected_index = 0;
287+
}
288+
}
289+
Err(e) => {
290+
app.p2pool_config_view.warning_message = Some(format!(
291+
"Failed to load P2Pool config: {}. Select another file.",
292+
e
293+
));
294+
app.p2pool_conf_path = None;
295+
app.p2pool_config = None;
296+
}
236297
}
237298
app.current_screen = CurrentScreen::P2PoolConfig;
238299
app.settings.p2pool_conf_path = Some(path.clone());
@@ -310,15 +371,28 @@ fn handle_action(action: AppAction, app: &mut App) -> Result<ControlFlow<()>> {
310371
should_save = false;
311372
}
312373
},
313-
1 => {
314-
app.p2pool_conf_path = Some(path.clone());
315-
if let Some(p) = path.to_str()
316-
&& let Ok(cfg) = P2PoolConfig::load(p)
317-
{
318-
app.p2pool_config = Some(cfg);
374+
1 => match P2PoolConfig::load(path.to_str().unwrap_or_default()) {
375+
Ok(cfg) => {
376+
if cfg.stratum.hostname.is_empty() {
377+
app.settings_view.save_error = Some(
378+
"Config appears invalid: stratum.hostname is empty."
379+
.to_string(),
380+
);
381+
should_save = false;
382+
} else {
383+
app.p2pool_config = Some(cfg);
384+
app.settings.p2pool_conf_path = Some(path.clone());
385+
app.p2pool_config_view.warning_message = None;
386+
app.p2pool_config_view.selected_index = 0;
387+
app.settings.p2pool_conf_path = Some(path.clone());
388+
}
319389
}
320-
app.settings.p2pool_conf_path = Some(path.clone());
321-
}
390+
Err(e) => {
391+
app.settings_view.save_error =
392+
Some(format!("Failed to load P2Pool config: {}", e));
393+
should_save = false;
394+
}
395+
},
322396
2 => app.settings.ln_conf_path = Some(path.clone()),
323397
3 => app.settings.shares_market_conf_path = Some(path.clone()),
324398
4 => app.settings.settings_dir_override = Some(path.clone()),
@@ -380,12 +454,40 @@ fn handle_action(action: AppAction, app: &mut App) -> Result<ControlFlow<()>> {
380454
app.settings_view.save_error = Some(format!("Save failed: {e}"));
381455
}
382456
}
457+
AppAction::CommitP2PoolEdit(index, value) => {
458+
if let Some(cfg) = app.p2pool_config.as_mut() {
459+
match apply_p2pool_edit(cfg, index, &value) {
460+
Ok(()) => {
461+
app.p2pool_config_view.warning_message = None;
462+
}
463+
Err(e) => {
464+
app.p2pool_config_view.warning_message = Some(e);
465+
}
466+
}
467+
}
468+
}
469+
470+
AppAction::SaveP2PoolConfig => {
471+
if let (Some(path), Some(cfg)) =
472+
(app.p2pool_conf_path.clone(), app.p2pool_config.as_ref())
473+
{
474+
match save_p2pool_config(&path, cfg) {
475+
Ok(()) => {
476+
app.p2pool_config_view.save_message =
477+
Some("Configuration correctly saved".to_string());
478+
}
479+
Err(e) => {
480+
app.p2pool_config_view.warning_message =
481+
Some(format!("Save failed: {}", e));
482+
}
483+
}
484+
}
485+
}
383486

384487
AppAction::None => {}
385488
}
386489

387490
Ok(ControlFlow::Continue(()))
388-
Ok(false)
389491
}
390492

391493
/// Matches the TOML type of an existing item and parses the new string
@@ -1119,7 +1221,7 @@ port = 46884
11191221
// Write a minimal but syntactically valid TOML file; P2PoolConfig::load
11201222
// may fail to parse it, but bootstrap_from_settings should at least set
11211223
// app.p2pool_conf_path regardless of whether the config is parseable.
1122-
std::fs::write(&path, "").unwrap();
1224+
let cfg = write_valid_p2pool_toml(&path);
11231225

11241226
let mut app = App::new();
11251227
app.settings.p2pool_conf_path = Some(path.clone());
@@ -1159,7 +1261,7 @@ port = 46884
11591261
let dir = tempdir().unwrap();
11601262
redirect_saves_to(&dir);
11611263
let path = dir.path().join("p2pool.toml");
1162-
std::fs::write(&path, "").unwrap();
1264+
let cfg = write_valid_p2pool_toml(&path);
11631265

11641266
let mut app = App::new();
11651267
app.explorer_trigger = Some(ExplorerTrigger::Settings(1));

0 commit comments

Comments
 (0)