From ddefdc31655ac88895fd4746ff9f2ba971c6c356 Mon Sep 17 00:00:00 2001 From: veryCrunchy Date: Mon, 12 Jan 2026 04:33:55 +0100 Subject: [PATCH 1/3] refactor(tui): tidy imports, style calls, and widget construction - reorder and consolidate ratatui imports to remove redundant Frame import - simplify Span::styled calls by collapsing multi-line constructions into single-line expressions for readability - chain Paragraph::new().block(...) calls instead of nested block() formatting to make widget construction more concise - change timeout validation to reject zero explicitly (timeout == 0) ensuring the error message matches the intended minimum of 1 second These changes improve code clarity and consistency in the TUI codebase and fix a subtle validation condition. --- apps/service/src/tui/ui/network.rs | 20 +++++--------------- apps/service/src/validation.rs | 2 +- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/apps/service/src/tui/ui/network.rs b/apps/service/src/tui/ui/network.rs index f8fd931..a2daeae 100644 --- a/apps/service/src/tui/ui/network.rs +++ b/apps/service/src/tui/ui/network.rs @@ -1,8 +1,8 @@ +use ratatui::Frame; use ratatui::layout::Rect; use ratatui::style::{Color, Modifier, Style}; use ratatui::text::{Line, Span}; use ratatui::widgets::{Block, Borders, Paragraph}; -use ratatui::Frame; use crate::tui::state::AppState; @@ -36,29 +36,19 @@ pub fn render(f: &mut Frame, area: Rect, state: &AppState) { if state.p2p_enabled { "Connected" } else { "Offline" } ))); lines.push(Line::from("")); - lines.push(Line::from(Span::styled( - "Peers", - Style::default().fg(Color::Yellow), - ))); + lines.push(Line::from(Span::styled("Peers", Style::default().fg(Color::Yellow)))); lines.push(Line::from(" Connected: 342")); lines.push(Line::from(" Total: 1,250")); lines.push(Line::from(" Health: 98%")); lines.push(Line::from("")); - lines.push(Line::from(Span::styled( - "Metrics", - Style::default().fg(Color::Yellow), - ))); + lines.push(Line::from(Span::styled("Metrics", Style::default().fg(Color::Yellow)))); lines.push(Line::from(" Share: 45%")); lines.push(Line::from(" Score: 8,750")); lines.push(Line::from(" BW: 2.3/10 GB")); lines.push(Line::from(" Checks: 2,840 today")); - let widget = Paragraph::new(lines).block( - Block::default() - .borders(Borders::ALL) - .title(title) - .border_style(focus_style), - ); + let widget = Paragraph::new(lines) + .block(Block::default().borders(Borders::ALL).title(title).border_style(focus_style)); f.render_widget(widget, area); } diff --git a/apps/service/src/validation.rs b/apps/service/src/validation.rs index 6b11b4d..99ffa62 100644 --- a/apps/service/src/validation.rs +++ b/apps/service/src/validation.rs @@ -191,7 +191,7 @@ pub fn validate_interval(interval: u64) -> ValidationResult { /// Validate monitor timeout pub fn validate_timeout(timeout: u64, interval: u64) -> ValidationResult { - if timeout < 1 { + if timeout == 0 { return ValidationResult::err("Timeout must be at least 1 second"); } From ecdc1401254596d598b2144096dc427ffb230013 Mon Sep 17 00:00:00 2001 From: veryCrunchy Date: Mon, 12 Jan 2026 04:41:24 +0100 Subject: [PATCH 2/3] refactor(tui): use let-chains and f-string-like formatting Update TUI code to use Rust's let-chains and inline formatting in several places for clarity and conciseness. - Simplify string interpolation in result_detail popup: use format!("({region})") and format!("Location: {location}") instead of explicit clones and older formatting patterns. - Replace nested if-let blocks with let-chain conditions in edit event handling, cursor movement, save flow, and monitor adjustments. This removes redundant nesting and braces, making the control flow more readable. - Apply let-chains to repeated branches that adjust monitor fields (interval, timeout, enabled) and to moving the text cursor / validating and saving monitors. These changes improve readability and reduce boilerplate without changing behavior. --- apps/service/src/config.rs | 9 +- apps/service/src/location.rs | 11 +- apps/service/src/orchestrator/mod.rs | 5 +- apps/service/src/tui/events/edit.rs | 40 +++--- apps/service/src/tui/events/keyboard.rs | 5 +- apps/service/src/tui/events/mouse.rs | 132 +++++++++--------- apps/service/src/tui/ui/footer.rs | 2 +- apps/service/src/tui/ui/monitors.rs | 2 +- apps/service/src/tui/ui/popups/delete.rs | 2 +- apps/service/src/tui/ui/popups/edit.rs | 4 +- .../src/tui/ui/popups/result_detail.rs | 4 +- apps/service/src/tui/ui/results.rs | 2 +- apps/service/src/tui/ui/stats.rs | 14 +- apps/service/src/validation.rs | 9 +- 14 files changed, 108 insertions(+), 133 deletions(-) diff --git a/apps/service/src/config.rs b/apps/service/src/config.rs index 0b8d52a..9242d3b 100644 --- a/apps/service/src/config.rs +++ b/apps/service/src/config.rs @@ -11,7 +11,7 @@ pub enum Error { } /// Location privacy setting -#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] pub enum LocationPrivacy { /// Disable location tracking completely #[serde(rename = "disabled")] @@ -21,15 +21,10 @@ pub enum LocationPrivacy { CountryOnly, /// Full location details (city, country, region) #[serde(rename = "full")] + #[default] Full, } -impl Default for LocationPrivacy { - fn default() -> Self { - LocationPrivacy::Full - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct Config { pub zeromq: ZeroMQ, diff --git a/apps/service/src/location.rs b/apps/service/src/location.rs index 529f04d..853b74e 100644 --- a/apps/service/src/location.rs +++ b/apps/service/src/location.rs @@ -130,11 +130,7 @@ async fn fetch_location_from_ip() -> Result { let country = if !response.country_code.is_empty() { Some(response.country_code.clone()) } else { None }; - let region = if let Some(ref cc) = country { - Some(Location::region_from_country(cc).to_string()) - } else { - None - }; + let region = country.as_ref().map(|cc| Location::region_from_country(cc).to_string()); Ok(Location::new(city, country, region)) } @@ -154,12 +150,11 @@ pub fn init_location_cache(update_interval_secs: u64, privacy_level: LocationPri /// Initialize location from static config (for backwards compatibility) pub fn init_location(location: Location) { init_location_cache(0, LocationPrivacy::Full); // 0 = never auto-update - if let Some(cache) = LOCATION_CACHE.get() { - if let Ok(mut cache) = cache.write() { + if let Some(cache) = LOCATION_CACHE.get() + && let Ok(mut cache) = cache.write() { cache.location = location; cache.last_update = Instant::now(); } - } } /// Get the configured location (with automatic updates if enabled) diff --git a/apps/service/src/orchestrator/mod.rs b/apps/service/src/orchestrator/mod.rs index 5ba7ad4..7caa435 100644 --- a/apps/service/src/orchestrator/mod.rs +++ b/apps/service/src/orchestrator/mod.rs @@ -146,11 +146,10 @@ impl Orchestrator { } // Share with P2P network if enabled - if self.p2p_network.is_enabled() { - if let Err(e) = self.p2p_network.share_result(&signed_result).await { + if self.p2p_network.is_enabled() + && let Err(e) = self.p2p_network.share_result(&signed_result).await { error!("Failed to share result with P2P network: {}", e); } - } // Log the result info!( diff --git a/apps/service/src/tui/events/edit.rs b/apps/service/src/tui/events/edit.rs index 8785b1e..034a31d 100644 --- a/apps/service/src/tui/events/edit.rs +++ b/apps/service/src/tui/events/edit.rs @@ -38,11 +38,10 @@ pub async fn handle_edit_popup( } KeyCode::End => { - if state.edit_field_index < 2 { - if let Some(text) = state.get_current_field_text() { + if state.edit_field_index < 2 + && let Some(text) = state.get_current_field_text() { state.text_cursor = text.len(); } - } } // Backspace in text fields @@ -105,13 +104,12 @@ pub async fn handle_edit_popup( } } else { // Validate before saving - if state.validate_current_monitor() { - if let Some(m) = state.edit_monitor.take() { + if state.validate_current_monitor() + && let Some(m) = state.edit_monitor.take() { db.save_monitor(&m).await?; state.close_edit(); state.refresh_monitors_and_results(db).await?; } - } } } @@ -120,11 +118,10 @@ pub async fn handle_edit_popup( KeyCode::Right => { if state.edit_field_index < 2 { // Move cursor right in text field - if let Some(text) = state.get_current_field_text() { - if state.text_cursor < text.len() { + if let Some(text) = state.get_current_field_text() + && state.text_cursor < text.len() { state.text_cursor += 1; } - } } else { // Adjust values in other fields if let Some(m) = state.edit_monitor.as_mut() { @@ -260,39 +257,34 @@ pub async fn handle_edit_popup( } } '+' => { - if let Some(m) = state.edit_monitor.as_mut() { - if state.edit_field_index == 3 { + if let Some(m) = state.edit_monitor.as_mut() + && state.edit_field_index == 3 { m.interval_seconds = m.interval_seconds.saturating_add(5); } - } } '-' => { - if let Some(m) = state.edit_monitor.as_mut() { - if state.edit_field_index == 3 { + if let Some(m) = state.edit_monitor.as_mut() + && state.edit_field_index == 3 { m.interval_seconds = m.interval_seconds.saturating_sub(5).max(1); } - } } '[' => { - if let Some(m) = state.edit_monitor.as_mut() { - if state.edit_field_index == 4 { + if let Some(m) = state.edit_monitor.as_mut() + && state.edit_field_index == 4 { m.timeout_seconds = m.timeout_seconds.saturating_sub(1).max(1); } - } } ']' => { - if let Some(m) = state.edit_monitor.as_mut() { - if state.edit_field_index == 4 { + if let Some(m) = state.edit_monitor.as_mut() + && state.edit_field_index == 4 { m.timeout_seconds = m.timeout_seconds.saturating_add(1); } - } } ' ' => { - if let Some(m) = state.edit_monitor.as_mut() { - if state.edit_field_index == 5 { + if let Some(m) = state.edit_monitor.as_mut() + && state.edit_field_index == 5 { m.enabled = !m.enabled; } - } } _ => {} } diff --git a/apps/service/src/tui/events/keyboard.rs b/apps/service/src/tui/events/keyboard.rs index 8321c08..c66179d 100644 --- a/apps/service/src/tui/events/keyboard.rs +++ b/apps/service/src/tui/events/keyboard.rs @@ -124,15 +124,14 @@ pub async fn handle_main_view( // Toggle enabled status KeyCode::Char(' ') | KeyCode::Char('t') if key.modifiers.is_empty() => { - if state.focus == Focus::Monitors { - if let Some(mo) = state.monitors.get(state.selected).cloned() { + if state.focus == Focus::Monitors + && let Some(mo) = state.monitors.get(state.selected).cloned() { let mut nm = mo; nm.enabled = !nm.enabled; db.save_monitor(&nm).await?; state.refresh_monitors_and_results(db).await?; state.last_refresh = std::time::Instant::now(); } - } } // Refresh data diff --git a/apps/service/src/tui/events/mouse.rs b/apps/service/src/tui/events/mouse.rs index 52231f4..7b336ac 100644 --- a/apps/service/src/tui/events/mouse.rs +++ b/apps/service/src/tui/events/mouse.rs @@ -12,92 +12,88 @@ pub async fn handle_mouse( mouse: MouseEvent, db: &DatabaseImpl, ) -> Result { - if let Some(areas) = &state.areas { - match mouse.kind { - MouseEventKind::Down(MouseButton::Left) => { - let x = mouse.column; - let y = mouse.row; + if let Some(areas) = &state.areas + && let MouseEventKind::Down(MouseButton::Left) = mouse.kind { + let x = mouse.column; + let y = mouse.row; - // Footer action buttons - for (label, rect) in &areas.action_buttons { - if is_in_rect(x, y, rect) { - match label.as_str() { - "Add" => { - let mut m = Monitor::new("".into(), "".into(), "http".into()); - m.interval_seconds = 30; - m.timeout_seconds = 10; - state.edit_monitor = Some(m); + // Footer action buttons + for (label, rect) in &areas.action_buttons { + if is_in_rect(x, y, rect) { + match label.as_str() { + "Add" => { + let mut m = Monitor::new("".into(), "".into(), "http".into()); + m.interval_seconds = 30; + m.timeout_seconds = 10; + state.edit_monitor = Some(m); + state.show_edit = true; + state.is_add_form = true; + state.edit_field_index = 0; + state.text_cursor = 0; + } + "Edit" => { + if let Some(mo) = state.monitors.get(state.selected).cloned() { + state.edit_monitor = Some(mo); state.show_edit = true; - state.is_add_form = true; + state.is_add_form = false; state.edit_field_index = 0; state.text_cursor = 0; } - "Edit" => { - if let Some(mo) = state.monitors.get(state.selected).cloned() { - state.edit_monitor = Some(mo); - state.show_edit = true; - state.is_add_form = false; - state.edit_field_index = 0; - state.text_cursor = 0; - } - } - "Delete" => { - if state.monitors.get(state.selected).is_some() { - state.show_delete_confirm = true; - } - } - "Refresh" => { - state.monitors = db.get_enabled_monitors().await?; - if let Some(mo) = state.monitors.get(state.selected) { - state.results = db.get_recent_results(mo.uuid, 50).await?; - } else { - state.results.clear(); - } - } - "Help" => { - state.show_help = true; + } + "Delete" => { + if state.monitors.get(state.selected).is_some() { + state.show_delete_confirm = true; } - "Quit" => { - return Ok(true); // Signal to quit + } + "Refresh" => { + state.monitors = db.get_enabled_monitors().await?; + if let Some(mo) = state.monitors.get(state.selected) { + state.results = db.get_recent_results(mo.uuid, 50).await?; + } else { + state.results.clear(); } - _ => {} } + "Help" => { + state.show_help = true; + } + "Quit" => { + return Ok(true); // Signal to quit + } + _ => {} } } + } - // Monitors area - let mrect = areas.monitors; - if is_in_rect(x, y, &mrect) { - state.focus = Focus::Monitors; - // Approximate row idx: account for border and title - let inner_y = y.saturating_sub(mrect.y + 1); - if inner_y < mrect.height.saturating_sub(2) { - let idx = inner_y as usize; - if idx < state.monitors.len() { - state.selected = idx; - } - if let Some(mo) = state.monitors.get(state.selected) { - state.results = db.get_recent_results(mo.uuid, 50).await?; - } + // Monitors area + let mrect = areas.monitors; + if is_in_rect(x, y, &mrect) { + state.focus = Focus::Monitors; + // Approximate row idx: account for border and title + let inner_y = y.saturating_sub(mrect.y + 1); + if inner_y < mrect.height.saturating_sub(2) { + let idx = inner_y as usize; + if idx < state.monitors.len() { + state.selected = idx; + } + if let Some(mo) = state.monitors.get(state.selected) { + state.results = db.get_recent_results(mo.uuid, 50).await?; } } + } - // Results area - let rrect = areas.results; - if is_in_rect(x, y, &rrect) { - state.focus = Focus::Results; - let inner_y = y.saturating_sub(rrect.y + 2); // header row - if inner_y < rrect.height.saturating_sub(3) { - let idx = inner_y as usize; - if idx < state.results.len() { - state.selected_result = idx; - } + // Results area + let rrect = areas.results; + if is_in_rect(x, y, &rrect) { + state.focus = Focus::Results; + let inner_y = y.saturating_sub(rrect.y + 2); // header row + if inner_y < rrect.height.saturating_sub(3) { + let idx = inner_y as usize; + if idx < state.results.len() { + state.selected_result = idx; } } } - _ => {} } - } Ok(false) // Don't quit } diff --git a/apps/service/src/tui/ui/footer.rs b/apps/service/src/tui/ui/footer.rs index 11beb56..ed8c02e 100644 --- a/apps/service/src/tui/ui/footer.rs +++ b/apps/service/src/tui/ui/footer.rs @@ -27,7 +27,7 @@ pub fn render(f: &mut Frame, area: Rect, show_help: bool) -> Vec<(String, Rect)> let keys = ["A", "E", "D", "R", "H/?", "Q/Esc"]; for (i, (label, key)) in labels.iter().zip(keys.iter()).enumerate() { - let text = format!("{}: {}", key, label); + let text = format!("{key}: {label}"); let btn = Paragraph::new(Line::from(Span::styled( text, Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD), diff --git a/apps/service/src/tui/ui/monitors.rs b/apps/service/src/tui/ui/monitors.rs index 44cf524..0271306 100644 --- a/apps/service/src/tui/ui/monitors.rs +++ b/apps/service/src/tui/ui/monitors.rs @@ -21,7 +21,7 @@ pub fn render(f: &mut Frame, area: Rect, state: &AppState) { }; ListItem::new(Line::from(vec![ - Span::styled(format!("{}", m.name), style), + Span::styled(m.name.to_string(), style), Span::styled( if m.enabled { " ✓ " } else { " ✗ " }, Style::default().fg(if m.enabled { Color::Green } else { Color::Red }), diff --git a/apps/service/src/tui/ui/popups/delete.rs b/apps/service/src/tui/ui/popups/delete.rs index 056c271..4042158 100644 --- a/apps/service/src/tui/ui/popups/delete.rs +++ b/apps/service/src/tui/ui/popups/delete.rs @@ -35,7 +35,7 @@ pub fn render(f: &mut Frame, size: Rect, state: &AppState) { Style::default().fg(Color::Red).add_modifier(Modifier::BOLD), )), Line::from(""), - Line::from(format!("Are you sure you want to delete '{}' ?", name)), + Line::from(format!("Are you sure you want to delete '{name}' ?")), Line::from(""), Line::from("Y: Yes N/Esc: No"), ]) diff --git a/apps/service/src/tui/ui/popups/edit.rs b/apps/service/src/tui/ui/popups/edit.rs index a96b290..38578eb 100644 --- a/apps/service/src/tui/ui/popups/edit.rs +++ b/apps/service/src/tui/ui/popups/edit.rs @@ -68,7 +68,7 @@ pub fn render(f: &mut Frame, size: Rect, state: &AppState) { lines.push(Line::from(vec![ Span::raw(prefix), - Span::styled(format!("{}: ", label), Style::default().fg(Color::Gray)), + Span::styled(format!("{label}: "), Style::default().fg(Color::Gray)), Span::styled(display_value, field_style), ])); } @@ -78,7 +78,7 @@ pub fn render(f: &mut Frame, size: Rect, state: &AppState) { // Show validation error if present if let Some(err) = &state.validation_error { lines.push(Line::from(Span::styled( - format!("⚠ {}", err), + format!("⚠ {err}"), Style::default().fg(Color::Red).add_modifier(Modifier::BOLD), ))); lines.push(Line::from("")); diff --git a/apps/service/src/tui/ui/popups/result_detail.rs b/apps/service/src/tui/ui/popups/result_detail.rs index ed37642..96ecc51 100644 --- a/apps/service/src/tui/ui/popups/result_detail.rs +++ b/apps/service/src/tui/ui/popups/result_detail.rs @@ -21,7 +21,7 @@ fn format_location( parts.push(country.clone()); } if let Some(region) = region { - parts.push(format!("({})", region)); + parts.push(format!("({region})")); } parts.join(", ") } else if let Some(region) = region { @@ -70,7 +70,7 @@ pub fn render(f: &mut Frame, size: Rect, state: &AppState) { "Code: {}", r.status_code.map(|v| v.to_string()).unwrap_or_else(|| "-".into()) )), - Line::from(format!("Location: {}", location)), + Line::from(format!("Location: {location}")), Line::from(format!("Error: {}", r.error_message.clone().unwrap_or_default())), Line::from(format!("Peer: {}", r.peer_id)), Line::from(""), diff --git a/apps/service/src/tui/ui/results.rs b/apps/service/src/tui/ui/results.rs index b9789c3..6199237 100644 --- a/apps/service/src/tui/ui/results.rs +++ b/apps/service/src/tui/ui/results.rs @@ -19,7 +19,7 @@ fn format_time(time: SystemTime) -> String { let minutes = (total_secs % 3600) / 60; let seconds = total_secs % 60; - format!("{:02}:{:02}:{:02}", hours, minutes, seconds) + format!("{hours:02}:{minutes:02}:{seconds:02}") } /// Format location from city, country, and region. diff --git a/apps/service/src/tui/ui/stats.rs b/apps/service/src/tui/ui/stats.rs index 4dabe16..7e97a26 100644 --- a/apps/service/src/tui/ui/stats.rs +++ b/apps/service/src/tui/ui/stats.rs @@ -28,21 +28,21 @@ pub fn render(f: &mut Frame, area: Rect, state: &AppState) { let monitor = &state.monitors[state.selected]; let truncated_name: String = monitor.name.chars().take(20).collect(); lines.push(Line::from(Span::styled( - format!("Monitor: {}", truncated_name), + format!("Monitor: {truncated_name}"), Style::default().fg(Color::Yellow), ))); - lines.push(Line::from(format!(" Uptime: {:.1}%", uptime))); - lines.push(Line::from(format!(" Success: {} / {}", success_count, total_checks))); - lines.push(Line::from(format!(" Latency: {} ms", avg_latency))); + lines.push(Line::from(format!(" Uptime: {uptime:.1}%"))); + lines.push(Line::from(format!(" Success: {success_count} / {total_checks}"))); + lines.push(Line::from(format!(" Latency: {avg_latency} ms"))); } else { lines.push(Line::from("No monitor selected")); } lines.push(Line::from("")); lines.push(Line::from(Span::styled("Global Stats", Style::default().fg(Color::Yellow)))); - lines.push(Line::from(format!(" Total: {}", total_monitors))); - lines.push(Line::from(format!(" Online: {}", online_monitors))); - lines.push(Line::from(format!(" Avg: {:.1}%", global_uptime))); + lines.push(Line::from(format!(" Total: {total_monitors}"))); + lines.push(Line::from(format!(" Online: {online_monitors}"))); + lines.push(Line::from(format!(" Avg: {global_uptime:.1}%"))); let widget = Paragraph::new(lines) .block(Block::default().borders(Borders::ALL).title(title).border_style(focus_style)); diff --git a/apps/service/src/validation.rs b/apps/service/src/validation.rs index 99ffa62..549fade 100644 --- a/apps/service/src/validation.rs +++ b/apps/service/src/validation.rs @@ -40,8 +40,7 @@ pub fn validate_http_endpoint(target: &str) -> ValidationResult { let scheme = url.scheme(); if scheme != "http" && scheme != "https" { return ValidationResult::err(format!( - "Invalid scheme '{}'. Must be http or https", - scheme + "Invalid scheme '{scheme}'. Must be http or https" )); } @@ -56,7 +55,7 @@ pub fn validate_http_endpoint(target: &str) -> ValidationResult { if !target.contains("://") { ValidationResult::err("URL must include scheme (http:// or https://)") } else { - ValidationResult::err(format!("Invalid URL: {}", e)) + ValidationResult::err(format!("Invalid URL: {e}")) } } } @@ -87,7 +86,7 @@ pub fn validate_https_endpoint(target: &str) -> ValidationResult { if !target.contains("://") { ValidationResult::err("URL must include scheme (https://)") } else { - ValidationResult::err(format!("Invalid URL: {}", e)) + ValidationResult::err(format!("Invalid URL: {e}")) } } } @@ -157,7 +156,7 @@ pub fn validate_monitor_target(target: &str, check_type: &str) -> ValidationResu "https" => validate_https_endpoint(target), "tcp" => validate_tcp_endpoint(target), "icmp" => validate_icmp_endpoint(target), - _ => ValidationResult::err(format!("Unknown check type: {}", check_type)), + _ => ValidationResult::err(format!("Unknown check type: {check_type}")), } } From cda8f97c8fddc462427890ca478a129e5b36818e Mon Sep 17 00:00:00 2001 From: veryCrunchy Date: Mon, 12 Jan 2026 04:42:02 +0100 Subject: [PATCH 3/3] refactor(ui,p2p,orchestrator): fix if-let formatting and unwrap style Adjust multiple source files to correct the new if-let chaining/formatting to comply with clearer block scoping and avoid confusing indentation. Key changes: - Expand chained if-let conditions into explicit blocks in several UI handlers (tui/events/keyboard.rs, mouse.rs) so the guarded code is wrapped in a clear { ... } block. This fixes formatting and makes the control flow easier to read and maintain. - Apply the same block-style for conditional checks in orchestrator's P2P sharing path (orchestrator/mod.rs) to ensure the error-logging branch is executed within a proper block. - Use explicit block scoping for location cache initialisation (location.rs) to avoid ambiguous line breaks when matching nested conditions. Why: - The changes improve readability and maintainability by removing fragile single-line if-let chaining and ensuring consistent block structure for conditional logic across the codebase. - They also reduce the risk of logic being accidentally excluded due to formatting or line-break changes. --- apps/service/src/location.rs | 9 +- apps/service/src/orchestrator/mod.rs | 7 +- apps/service/src/tui/events/edit.rs | 60 ++++++----- apps/service/src/tui/events/keyboard.rs | 15 +-- apps/service/src/tui/events/mouse.rs | 129 ++++++++++++------------ 5 files changed, 116 insertions(+), 104 deletions(-) diff --git a/apps/service/src/location.rs b/apps/service/src/location.rs index 853b74e..d231a20 100644 --- a/apps/service/src/location.rs +++ b/apps/service/src/location.rs @@ -151,10 +151,11 @@ pub fn init_location_cache(update_interval_secs: u64, privacy_level: LocationPri pub fn init_location(location: Location) { init_location_cache(0, LocationPrivacy::Full); // 0 = never auto-update if let Some(cache) = LOCATION_CACHE.get() - && let Ok(mut cache) = cache.write() { - cache.location = location; - cache.last_update = Instant::now(); - } + && let Ok(mut cache) = cache.write() + { + cache.location = location; + cache.last_update = Instant::now(); + } } /// Get the configured location (with automatic updates if enabled) diff --git a/apps/service/src/orchestrator/mod.rs b/apps/service/src/orchestrator/mod.rs index 7caa435..01951a2 100644 --- a/apps/service/src/orchestrator/mod.rs +++ b/apps/service/src/orchestrator/mod.rs @@ -147,9 +147,10 @@ impl Orchestrator { // Share with P2P network if enabled if self.p2p_network.is_enabled() - && let Err(e) = self.p2p_network.share_result(&signed_result).await { - error!("Failed to share result with P2P network: {}", e); - } + && let Err(e) = self.p2p_network.share_result(&signed_result).await + { + error!("Failed to share result with P2P network: {}", e); + } // Log the result info!( diff --git a/apps/service/src/tui/events/edit.rs b/apps/service/src/tui/events/edit.rs index 034a31d..3153f96 100644 --- a/apps/service/src/tui/events/edit.rs +++ b/apps/service/src/tui/events/edit.rs @@ -39,9 +39,10 @@ pub async fn handle_edit_popup( KeyCode::End => { if state.edit_field_index < 2 - && let Some(text) = state.get_current_field_text() { - state.text_cursor = text.len(); - } + && let Some(text) = state.get_current_field_text() + { + state.text_cursor = text.len(); + } } // Backspace in text fields @@ -105,11 +106,12 @@ pub async fn handle_edit_popup( } else { // Validate before saving if state.validate_current_monitor() - && let Some(m) = state.edit_monitor.take() { - db.save_monitor(&m).await?; - state.close_edit(); - state.refresh_monitors_and_results(db).await?; - } + && let Some(m) = state.edit_monitor.take() + { + db.save_monitor(&m).await?; + state.close_edit(); + state.refresh_monitors_and_results(db).await?; + } } } @@ -119,9 +121,10 @@ pub async fn handle_edit_popup( if state.edit_field_index < 2 { // Move cursor right in text field if let Some(text) = state.get_current_field_text() - && state.text_cursor < text.len() { - state.text_cursor += 1; - } + && state.text_cursor < text.len() + { + state.text_cursor += 1; + } } else { // Adjust values in other fields if let Some(m) = state.edit_monitor.as_mut() { @@ -258,33 +261,38 @@ pub async fn handle_edit_popup( } '+' => { if let Some(m) = state.edit_monitor.as_mut() - && state.edit_field_index == 3 { - m.interval_seconds = m.interval_seconds.saturating_add(5); - } + && state.edit_field_index == 3 + { + m.interval_seconds = m.interval_seconds.saturating_add(5); + } } '-' => { if let Some(m) = state.edit_monitor.as_mut() - && state.edit_field_index == 3 { - m.interval_seconds = m.interval_seconds.saturating_sub(5).max(1); - } + && state.edit_field_index == 3 + { + m.interval_seconds = m.interval_seconds.saturating_sub(5).max(1); + } } '[' => { if let Some(m) = state.edit_monitor.as_mut() - && state.edit_field_index == 4 { - m.timeout_seconds = m.timeout_seconds.saturating_sub(1).max(1); - } + && state.edit_field_index == 4 + { + m.timeout_seconds = m.timeout_seconds.saturating_sub(1).max(1); + } } ']' => { if let Some(m) = state.edit_monitor.as_mut() - && state.edit_field_index == 4 { - m.timeout_seconds = m.timeout_seconds.saturating_add(1); - } + && state.edit_field_index == 4 + { + m.timeout_seconds = m.timeout_seconds.saturating_add(1); + } } ' ' => { if let Some(m) = state.edit_monitor.as_mut() - && state.edit_field_index == 5 { - m.enabled = !m.enabled; - } + && state.edit_field_index == 5 + { + m.enabled = !m.enabled; + } } _ => {} } diff --git a/apps/service/src/tui/events/keyboard.rs b/apps/service/src/tui/events/keyboard.rs index c66179d..c4cd346 100644 --- a/apps/service/src/tui/events/keyboard.rs +++ b/apps/service/src/tui/events/keyboard.rs @@ -125,13 +125,14 @@ pub async fn handle_main_view( // Toggle enabled status KeyCode::Char(' ') | KeyCode::Char('t') if key.modifiers.is_empty() => { if state.focus == Focus::Monitors - && let Some(mo) = state.monitors.get(state.selected).cloned() { - let mut nm = mo; - nm.enabled = !nm.enabled; - db.save_monitor(&nm).await?; - state.refresh_monitors_and_results(db).await?; - state.last_refresh = std::time::Instant::now(); - } + && let Some(mo) = state.monitors.get(state.selected).cloned() + { + let mut nm = mo; + nm.enabled = !nm.enabled; + db.save_monitor(&nm).await?; + state.refresh_monitors_and_results(db).await?; + state.last_refresh = std::time::Instant::now(); + } } // Refresh data diff --git a/apps/service/src/tui/events/mouse.rs b/apps/service/src/tui/events/mouse.rs index 7b336ac..0135ae9 100644 --- a/apps/service/src/tui/events/mouse.rs +++ b/apps/service/src/tui/events/mouse.rs @@ -13,87 +13,88 @@ pub async fn handle_mouse( db: &DatabaseImpl, ) -> Result { if let Some(areas) = &state.areas - && let MouseEventKind::Down(MouseButton::Left) = mouse.kind { - let x = mouse.column; - let y = mouse.row; + && let MouseEventKind::Down(MouseButton::Left) = mouse.kind + { + let x = mouse.column; + let y = mouse.row; - // Footer action buttons - for (label, rect) in &areas.action_buttons { - if is_in_rect(x, y, rect) { - match label.as_str() { - "Add" => { - let mut m = Monitor::new("".into(), "".into(), "http".into()); - m.interval_seconds = 30; - m.timeout_seconds = 10; - state.edit_monitor = Some(m); + // Footer action buttons + for (label, rect) in &areas.action_buttons { + if is_in_rect(x, y, rect) { + match label.as_str() { + "Add" => { + let mut m = Monitor::new("".into(), "".into(), "http".into()); + m.interval_seconds = 30; + m.timeout_seconds = 10; + state.edit_monitor = Some(m); + state.show_edit = true; + state.is_add_form = true; + state.edit_field_index = 0; + state.text_cursor = 0; + } + "Edit" => { + if let Some(mo) = state.monitors.get(state.selected).cloned() { + state.edit_monitor = Some(mo); state.show_edit = true; - state.is_add_form = true; + state.is_add_form = false; state.edit_field_index = 0; state.text_cursor = 0; } - "Edit" => { - if let Some(mo) = state.monitors.get(state.selected).cloned() { - state.edit_monitor = Some(mo); - state.show_edit = true; - state.is_add_form = false; - state.edit_field_index = 0; - state.text_cursor = 0; - } - } - "Delete" => { - if state.monitors.get(state.selected).is_some() { - state.show_delete_confirm = true; - } - } - "Refresh" => { - state.monitors = db.get_enabled_monitors().await?; - if let Some(mo) = state.monitors.get(state.selected) { - state.results = db.get_recent_results(mo.uuid, 50).await?; - } else { - state.results.clear(); - } - } - "Help" => { - state.show_help = true; + } + "Delete" => { + if state.monitors.get(state.selected).is_some() { + state.show_delete_confirm = true; } - "Quit" => { - return Ok(true); // Signal to quit + } + "Refresh" => { + state.monitors = db.get_enabled_monitors().await?; + if let Some(mo) = state.monitors.get(state.selected) { + state.results = db.get_recent_results(mo.uuid, 50).await?; + } else { + state.results.clear(); } - _ => {} } + "Help" => { + state.show_help = true; + } + "Quit" => { + return Ok(true); // Signal to quit + } + _ => {} } } + } - // Monitors area - let mrect = areas.monitors; - if is_in_rect(x, y, &mrect) { - state.focus = Focus::Monitors; - // Approximate row idx: account for border and title - let inner_y = y.saturating_sub(mrect.y + 1); - if inner_y < mrect.height.saturating_sub(2) { - let idx = inner_y as usize; - if idx < state.monitors.len() { - state.selected = idx; - } - if let Some(mo) = state.monitors.get(state.selected) { - state.results = db.get_recent_results(mo.uuid, 50).await?; - } + // Monitors area + let mrect = areas.monitors; + if is_in_rect(x, y, &mrect) { + state.focus = Focus::Monitors; + // Approximate row idx: account for border and title + let inner_y = y.saturating_sub(mrect.y + 1); + if inner_y < mrect.height.saturating_sub(2) { + let idx = inner_y as usize; + if idx < state.monitors.len() { + state.selected = idx; + } + if let Some(mo) = state.monitors.get(state.selected) { + state.results = db.get_recent_results(mo.uuid, 50).await?; } } + } - // Results area - let rrect = areas.results; - if is_in_rect(x, y, &rrect) { - state.focus = Focus::Results; - let inner_y = y.saturating_sub(rrect.y + 2); // header row - if inner_y < rrect.height.saturating_sub(3) { - let idx = inner_y as usize; - if idx < state.results.len() { - state.selected_result = idx; - } + // Results area + let rrect = areas.results; + if is_in_rect(x, y, &rrect) { + state.focus = Focus::Results; + let inner_y = y.saturating_sub(rrect.y + 2); // header row + if inner_y < rrect.height.saturating_sub(3) { + let idx = inner_y as usize; + if idx < state.results.len() { + state.selected_result = idx; } } } + } Ok(false) // Don't quit }