Add editing p2poolv2 config file#20
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Adds support for opening, editing, and saving a p2poolv2 config.toml from the TUI by introducing a “flattened rows” adapter around the deeply-nested p2poolv2_config::Config, plus a dedicated config view and new app actions to commit edits and persist them back to disk.
Changes:
- Introduces a
p2poolv2_configadapter that flattensConfiginto editable rows and applies edits back to the nested struct. - Updates the TUI to navigate and edit P2Pool config entries, including sensitive-field masking.
- Adds save logic intended to patch the original TOML in-place (preserving comments/formatting) and expands integration tests around P2Pool config flows.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/p2poolv2_config.rs |
New adapter layer (flatten_config / apply_edit) + schema metadata + unit tests. |
src/components/p2pool_config_view.rs |
Reworks the P2Pool config screen into a list/detail editor with edit mode and masking. |
src/main.rs |
Wires P2Pool config screen input handling, commit/save actions, and TOML patch-based saving + tests. |
src/app.rs |
Adds new AppActions and stores P2PoolConfigView in app state. |
src/lib.rs |
Exposes p2poolv2_config module publicly. |
Cargo.toml / Cargo.lock |
Adds TOML editing + Bitcoin network parsing deps and updates lockfile accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ratatui = "0.29.0" | ||
| p2poolv2_config = { git = "https://github.com/p2poolv2/p2poolv2", package = "p2poolv2_config" } | ||
| bitcoin = "0.32.5" | ||
| toml = "0.8" |
There was a problem hiding this comment.
removed the unused toml dependency.
| let panels = Layout::default() | ||
| .direction(Direction::Horizontal) | ||
| .constraints([Constraint::Percentage(45), Constraint::Percentage(55)]) | ||
| .split(area); |
There was a problem hiding this comment.
updated the config view to render warning and save messages so validation errors and save feedback are visible.
| if let Some(table) = doc.get_mut(§ion).and_then(|v| v.as_table_mut()) { | ||
| // Only update keys that already exist in the file to avoid | ||
| // injecting fields the user intentionally omitted | ||
| if table.contains_key(key) { | ||
| table[key] = toml_edit::value(entry.value.clone()); | ||
| } |
There was a problem hiding this comment.
updated
now instead of always calling toml_edit::value(entry.value.clone()) (which always produces a string), we now call typed_toml_item_like which inspects the existing item's type in the document and parses the new value into that same type.
| // Needs a real sample config — adjust path to your sample | ||
| if let Ok(cfg) = P2PoolConfig::load("../config.sample.toml") { | ||
| let mut app = App::new(); | ||
| app.p2pool_config = Some(cfg); | ||
| // Find port index | ||
| let entries = flatten_config(app.p2pool_config.as_ref().unwrap()); | ||
| let port_idx = entries.iter().position(|e| e.key == "port").unwrap(); | ||
| handle_action( | ||
| AppAction::CommitP2PoolEdit(port_idx, "notanumber".to_string()), | ||
| &mut app, | ||
| ) | ||
| .unwrap(); | ||
| assert!(app.p2pool_config_view.warning_message.is_some()); | ||
| } |
There was a problem hiding this comment.
updated
now config is written inline so the test is fully hermetic, expect instead of if let Ok so a parse failure is a real test failure
| if let Ok(cfg) = P2PoolConfig::load(path.to_str().unwrap()) { | ||
| let mut app = App::new(); | ||
| app.p2pool_config = Some(cfg); | ||
| app.p2pool_config_view.warning_message = Some("old warning".to_string()); | ||
|
|
||
| let entries = flatten_config(app.p2pool_config.as_ref().unwrap()); |
There was a problem hiding this comment.
replaced all if let ok with expect any future breakage in the fixture TOML will cause a expect panic rather than a silent pass.
| // Point at a directory that doesn't exist so writing fails | ||
| app.p2pool_conf_path = Some(std::path::PathBuf::from("/nonexistent/config.toml")); |
| fn apply_edit_unknown_field_hits_fallback_branch() { | ||
| use super::apply_edit; | ||
|
|
||
| let mut cfg = make_config(); | ||
|
|
||
| // Out of bounds → triggers error path |
There was a problem hiding this comment.
Updated!
refactored the apply_edit slightly to extract the dispatch logic so tests can inject a fake entry directly, and split this into separate tests for index bounds and unknown-field handling.
…ion errors and save feedback are visible
…in the document and parses the new value into that same type.
There was a problem hiding this comment.
Pressing "q" while editing a P2PoolV2 config field quits the application. We should add P2PoolConfig here to avoid this behaviour.
let text_input_active =
(app.current_screen == CurrentScreen::BitcoinConfig
&& !app.bitcoin_config_view.sidebar_focused
&& app.bitcoin_config_view.editing)
|| (app.current_screen == CurrentScreen::P2PoolConfig
&& !app.p2pool_config_view.sidebar_focused
&& app.p2pool_config_view.editing);
| .map_err(|e| anyhow::anyhow!("Failed to parse P2Pool config TOML: {}", e))?; | ||
|
|
||
| // Walk every flattened entry and patch the matching TOML key | ||
| for entry in flatten_config(cfg) { |
There was a problem hiding this comment.
dial_peers field edits are not saved, flatten_config encodes the field as a CSV string like this n.dial_peers.join(","). When at line 551 typed_toml_item_like is called we get the "Unsupported TOML value type for key: {}" because existing is a TOML array and typed_toml_item_like doesn't handle arrays.
We could fix it adding a new if statement to typed_toml_item_like in order to handle arrays: if let Some(arr) = existing.as_array()
| } | ||
| } | ||
| app.current_screen = CurrentScreen::P2PoolConfig; | ||
| app.settings.p2pool_conf_path = Some(path.clone()); |
There was a problem hiding this comment.
These lines run even if the config fails to load. On next startup bootstrap_from_settings tries to load this path, fails and prints an eprintln!
There was a problem hiding this comment.
Thanks! updated!!
There was a problem hiding this comment.
CurrentScreen::P2PoolConfig has its own explicit arm, no need here.
_ => sidebar_nav(key.code, app),
| } | ||
| } | ||
|
|
||
| // Logic to switch between sidebar items |
There was a problem hiding this comment.
We should add also P2PoolConfig here, like it's done for BitcoinConfig, in order to cleanup messages and editing state when navigating away from it.
There was a problem hiding this comment.
Thanks!! Updated !!
Open, edit, save config.toml file
p2pool_config.rs(adapter forConfig)p2pool_config_view.rs(like BitcoinConfigView) Add editing Bitcoin config file #19The imported
P2poolv2_Configis deeply nested and not suitable for TUI lists.The adapter flattens it into rows and maps edits back.
Demo