From 0039f985b27a888bb469bd7084de69dfce989df1 Mon Sep 17 00:00:00 2001 From: xscriptor Date: Sat, 20 Jun 2026 20:06:37 +0200 Subject: [PATCH] fix clippy warnings and fmt --- crates/xtop-cli/src/main.rs | 6 +-- crates/xtop-cli/src/mcp.rs | 8 ++-- .../src/application/plugin_manager.rs | 16 +++---- crates/xtop-core/src/domain/plugin.rs | 7 +-- plugins/xtop-plugin-sentinel/src/lib.rs | 43 ++++++++----------- 5 files changed, 36 insertions(+), 44 deletions(-) diff --git a/crates/xtop-cli/src/main.rs b/crates/xtop-cli/src/main.rs index f8ed928..c66a4e5 100644 --- a/crates/xtop-cli/src/main.rs +++ b/crates/xtop-cli/src/main.rs @@ -1,6 +1,6 @@ use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers}; use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::time::{Duration, Instant}; use xtop_core::application::plugin_manager::PluginManager; use xtop_core::application::state::{AppState, Config, InputMode, PalettePage}; @@ -174,7 +174,7 @@ fn save_config(state: &AppState) { let _ = config::save_config(&cfg); } -fn build_plugin_manager(state: &mut AppState, cfg_dir: &PathBuf) -> PluginManager { +fn build_plugin_manager(state: &mut AppState, cfg_dir: &Path) -> PluginManager { let plugins_dir = cfg_dir.join("plugins"); fs::create_dir_all(&plugins_dir).ok(); let mut mgr = PluginManager::new(plugins_dir); @@ -417,7 +417,7 @@ fn cmd_plugin_install(name_or_url: &str) -> anyhow::Result<()> { println!("Building xtop with {pkg_name} ..."); let build = std::process::Command::new("cargo") .args(["build", "--release"]) - .current_dir(&workspace_dir) + .current_dir(workspace_dir) .status() .map_err(|e| anyhow::anyhow!("cargo build failed: {e}"))?; if !build.success() { diff --git a/crates/xtop-cli/src/mcp.rs b/crates/xtop-cli/src/mcp.rs index 1c84a27..9a7e39e 100644 --- a/crates/xtop-cli/src/mcp.rs +++ b/crates/xtop-cli/src/mcp.rs @@ -4,7 +4,7 @@ //! MCP module (`xtop_plugin_sentinel::mcp::run_server`) which handles the //! actual stdin/stdout MCP protocol loop. -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use xtop_core::application::plugin_manager::PluginManager; use xtop_core::application::state::AppState; use xtop_core::infrastructure::composite_provider::CompositeProvider; @@ -27,7 +27,7 @@ pub fn run_mcp_server() -> anyhow::Result<()> { // Delegate to Sentinel's MCP module #[cfg(feature = "plugin-sentinel")] { - return xtop_plugin_sentinel::mcp::run_server(&mut state); + xtop_plugin_sentinel::mcp::run_server(&mut state) } #[cfg(not(feature = "plugin-sentinel"))] @@ -42,7 +42,7 @@ fn config_dir() -> PathBuf { xtop_core::infrastructure::config::config_dir() } -fn build_plugin_manager(state: &mut AppState, cfg_dir: &PathBuf) -> PluginManager { +fn build_plugin_manager(state: &mut AppState, cfg_dir: &Path) -> PluginManager { let plugins_dir = cfg_dir.join("plugins"); std::fs::create_dir_all(&plugins_dir).ok(); let mut mgr = PluginManager::new(plugins_dir); @@ -58,7 +58,7 @@ fn build_plugin_manager(state: &mut AppState, cfg_dir: &PathBuf) -> PluginManage mgr } -fn initialize_state(cfg_dir: &PathBuf) -> anyhow::Result { +fn initialize_state(cfg_dir: &Path) -> anyhow::Result { let sysinfo_provider = SysinfoProvider::new(); let composite = CompositeProvider::new(Box::new(sysinfo_provider)); diff --git a/crates/xtop-core/src/application/plugin_manager.rs b/crates/xtop-core/src/application/plugin_manager.rs index b955043..5ffaf43 100644 --- a/crates/xtop-core/src/application/plugin_manager.rs +++ b/crates/xtop-core/src/application/plugin_manager.rs @@ -67,13 +67,13 @@ impl PluginManager { Ok(()) } - fn plugin_has_capability(plugin: &Box, cap: &PluginCapability) -> bool { + fn plugin_has_capability(plugin: &dyn Plugin, cap: &PluginCapability) -> bool { plugin.manifest().capabilities.contains(cap) } fn build_context<'a>( base: &std::path::Path, - plugin: &Box, + plugin: &dyn Plugin, state: &'a mut AppState, ) -> PluginContext<'a> { let id = plugin.manifest().id.clone(); @@ -91,7 +91,7 @@ impl PluginManager { let base = self.plugin_data_base.clone(); for plugin in &mut self.plugins { let id = plugin.manifest().id.clone(); - let mut ctx = Self::build_context(&base, plugin, state); + let mut ctx = Self::build_context(&base, &**plugin, state); if let Err(e) = plugin.on_tick(&mut ctx) { eprintln!("[plugin:{id}] tick error: {e}"); } @@ -104,7 +104,7 @@ impl PluginManager { let base = self.plugin_data_base.clone(); for plugin in &mut self.plugins { let id = plugin.manifest().id.clone(); - let mut ctx = Self::build_context(&base, plugin, state); + let mut ctx = Self::build_context(&base, &**plugin, state); match plugin.on_key(&mut ctx, key) { Ok(true) => return true, Err(e) => eprintln!("[plugin:{id}] key error: {e}"), @@ -119,7 +119,7 @@ impl PluginManager { pub fn collect_data_providers(&self) -> Vec> { let mut providers: Vec> = Vec::new(); for plugin in &self.plugins { - if Self::plugin_has_capability(plugin, &PluginCapability::ReadSystemInfo) { + if Self::plugin_has_capability(&**plugin, &PluginCapability::ReadSystemInfo) { if let Some(provider) = plugin.data_provider() { providers.push(provider); } @@ -133,7 +133,7 @@ impl PluginManager { pub fn collect_widgets(&self) -> Vec { let mut widgets: Vec = Vec::new(); for plugin in &self.plugins { - if Self::plugin_has_capability(plugin, &PluginCapability::RenderWidgets) { + if Self::plugin_has_capability(&**plugin, &PluginCapability::RenderWidgets) { if let Some(widget) = plugin.widget() { widgets.push(widget); } @@ -157,7 +157,7 @@ impl PluginManager { if plugin.manifest().id != plugin_id { continue; } - let mut ctx = Self::build_context(&base, plugin, state); + let mut ctx = Self::build_context(&base, &**plugin, state); return plugin.execute(&mut ctx, action, params); } Err(PluginError::Recoverable(format!( @@ -180,7 +180,7 @@ impl PluginManager { let base = self.plugin_data_base.clone(); for plugin in &mut self.plugins { let id = plugin.manifest().id.clone(); - let mut ctx = Self::build_context(&base, plugin, state); + let mut ctx = Self::build_context(&base, &**plugin, state); if let Err(e) = plugin.on_disable(&mut ctx) { eprintln!("[plugin:{id}] disable error: {e}"); } diff --git a/crates/xtop-core/src/domain/plugin.rs b/crates/xtop-core/src/domain/plugin.rs index d6336e6..22755dd 100644 --- a/crates/xtop-core/src/domain/plugin.rs +++ b/crates/xtop-core/src/domain/plugin.rs @@ -55,12 +55,13 @@ impl std::fmt::Display for PluginError { impl std::error::Error for PluginError {} +type RenderFn = + std::sync::Arc; + /// A widget that a plugin registers for rendering in the TUI. pub struct WidgetRegistration { pub name: String, - pub render: std::sync::Arc< - dyn Fn(&mut ratatui::Frame, &AppState, ratatui::prelude::Rect) + Send + Sync, - >, + pub render: RenderFn, } impl Debug for WidgetRegistration { diff --git a/plugins/xtop-plugin-sentinel/src/lib.rs b/plugins/xtop-plugin-sentinel/src/lib.rs index 133c9fe..98d7e71 100644 --- a/plugins/xtop-plugin-sentinel/src/lib.rs +++ b/plugins/xtop-plugin-sentinel/src/lib.rs @@ -112,6 +112,12 @@ pub struct SentinelPlugin { spawn_history: HashMap>, } +impl Default for SentinelPlugin { + fn default() -> Self { + Self::new() + } +} + impl SentinelPlugin { pub fn new() -> Self { Self { @@ -218,10 +224,10 @@ impl SentinelPlugin { fields.iter().any(|f| match *f { "name" => re.is_match(&p.name), "cmd" => re.is_match(&p.cmd), - "user" => p.user_id.as_deref().map_or(false, |u| re.is_match(u)), + "user" => p.user_id.as_deref().is_some_and(|u| re.is_match(u)), "state" => re.is_match(&p.state), - "exe" => p.exe_path.as_deref().map_or(false, |e| re.is_match(e)), - "cwd" => p.cwd.as_deref().map_or(false, |c| re.is_match(c)), + "exe" => p.exe_path.as_deref().is_some_and(|e| re.is_match(e)), + "cwd" => p.cwd.as_deref().is_some_and(|c| re.is_match(c)), _ => false, }) }) @@ -258,7 +264,7 @@ impl SentinelPlugin { procs.retain(|p| { re.is_match(&p.name) || re.is_match(&p.cmd) - || p.exe_path.as_deref().map_or(false, |e| re.is_match(e)) + || p.exe_path.as_deref().is_some_and(|e| re.is_match(e)) }); } @@ -328,10 +334,7 @@ impl SentinelPlugin { /// Rule 3: Process masquerading (name != exe file stem OR system name not at canonical path). fn rule_masquerading(&self, proc: &ProcessInfo) -> Option { - let exe = match proc.exe_path.as_deref() { - Some(e) => e, - None => return None, - }; + let exe = proc.exe_path.as_deref()?; // Extract file stem from exe let stem = std::path::Path::new(exe) .file_stem() @@ -383,14 +386,8 @@ impl SentinelPlugin { /// Rule 4: Privilege escalation (EUID != UID). fn rule_privilege_escalation(&self, proc: &ProcessInfo) -> Option { - let euid = match proc.effective_user_id.as_deref() { - Some(u) => u, - None => return None, - }; - let uid = match proc.user_id.as_deref() { - Some(u) => u, - None => return None, - }; + let euid = proc.effective_user_id.as_deref()?; + let uid = proc.user_id.as_deref()?; if euid == uid { return None; } @@ -433,14 +430,8 @@ impl SentinelPlugin { proc: &ProcessInfo, parent_map: &HashMap, ) -> Option { - let ppid = match proc.parent_pid { - Some(pid) => pid, - None => return None, - }; - let parent = match parent_map.get(&ppid) { - Some(p) => p, - None => return None, - }; + let ppid = proc.parent_pid?; + let parent = parent_map.get(&ppid)?; let parent_lower = parent.name.to_lowercase(); let is_browser = BROWSER_NAMES.iter().any(|b| parent_lower.contains(b)); if !is_browser { @@ -479,7 +470,7 @@ impl SentinelPlugin { if KNOWN_THREAT_CMDS.iter().any(|t| { Regex::new(t) .ok() - .map_or(false, |re| re.is_match(&cmd_joined)) + .is_some_and(|re| re.is_match(&cmd_joined)) }) { return Some(SentinelAlert::new( "known_threat_pattern", @@ -695,7 +686,7 @@ impl Plugin for SentinelPlugin { fn on_tick(&mut self, ctx: &mut PluginContext) -> Result<(), PluginError> { self.tick_count += 1; - if self.tick_count % 5 == 0 { + if self.tick_count.is_multiple_of(5) { self.alerts = self.analyze_processes(ctx); } Ok(())