From d5fb4467632acdbce5754fa9e8ee820a7d995255 Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Mon, 11 Aug 2025 12:22:54 -0300 Subject: [PATCH] refactor: unify status data generation and output formatting Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) --- src/modes/server.rs | 86 +---------- src/modes/status.rs | 364 ++++++++++++++++++-------------------------- 2 files changed, 151 insertions(+), 299 deletions(-) diff --git a/src/modes/server.rs b/src/modes/server.rs index a27cab7..02954bc 100644 --- a/src/modes/server.rs +++ b/src/modes/server.rs @@ -25,7 +25,7 @@ use tower_http::trace::TraceLayer; use crate::compression_engine::{CompressionType, get_compression_engine}; use crate::db; use crate::Args; -use crate::modes::status::{PathInfo, CompressionInfo, MetaPluginInfo, StatusInfo}; +use crate::modes::status::{StatusInfo, generate_status_info}; use crate::compression_engine::{CompressionType as CompressionTypeEnum, COMPRESSION_PROGRAMS}; use crate::compression_engine::program::CompressionEngineProgram; use crate::meta_plugin::{MetaPluginType, get_meta_plugin}; @@ -220,89 +220,7 @@ async fn handle_status( let mut db_path = state.data_dir.clone(); db_path.push("keep-1.db"); - let path_info = PathInfo { - data: state.data_dir.to_string_lossy().to_string(), - database: db_path.to_string_lossy().to_string(), - }; - - let default_type = crate::compression_engine::default_compression_type(); - let mut compression_info = Vec::new(); - - // Sort compression types by their string representation - let mut sorted_compression_types: Vec = CompressionTypeEnum::iter().collect(); - sorted_compression_types.sort_by_key(|ct| ct.to_string()); - - for compression_type in sorted_compression_types { - let compression_program: CompressionEngineProgram = - match &COMPRESSION_PROGRAMS[compression_type.clone()] { - Some(compression_program) => compression_program.clone(), - None => CompressionEngineProgram { - program: "".to_string(), - compress: Vec::new(), - decompress: Vec::new(), - supported: true, - }, - }; - - let is_default = compression_type == default_type; - let binary = if compression_program.program.is_empty() { - "".to_string() - } else { - compression_program.program - }; - - compression_info.push(CompressionInfo { - compression_type: compression_type.to_string(), - found: compression_program.supported, - default: is_default, - binary, - compress: compression_program.compress.join(" "), - decompress: compression_program.decompress.join(" "), - }); - } - - let mut meta_plugin_info = Vec::new(); - - // Sort meta plugin types by their meta name - let mut sorted_meta_plugins: Vec = MetaPluginType::iter().collect(); - sorted_meta_plugins.sort_by_key(|meta_plugin_type| { - let mut meta_plugin = get_meta_plugin(meta_plugin_type.clone()); - meta_plugin.meta_name() - }); - - for meta_plugin_type in sorted_meta_plugins { - let mut meta_plugin = get_meta_plugin(meta_plugin_type.clone()); - let is_supported = meta_plugin.is_supported(); - let is_enabled = meta_plugin_types.contains(&meta_plugin_type); - - let (binary_display, args_display) = if !is_supported { - ("".to_string(), "".to_string()) - } else { - if meta_plugin.is_internal() { - ("".to_string(), "".to_string()) - } else { - if let Some((program, args)) = meta_plugin.program_info() { - (program.to_string(), args.join(" ")) - } else { - ("".to_string(), "".to_string()) - } - } - }; - - meta_plugin_info.push(MetaPluginInfo { - meta_name: meta_plugin.meta_name(), - found: is_supported, - enabled: is_enabled, - binary: binary_display, - args: args_display, - }); - } - - let status_info = StatusInfo { - paths: path_info, - compression: compression_info, - meta_plugins: meta_plugin_info, - }; + let status_info = generate_status_info(state.data_dir.clone(), db_path, &meta_plugin_types); let response = ApiResponse { success: true, diff --git a/src/modes/status.rs b/src/modes/status.rs index 2bcae7a..f8966db 100644 --- a/src/modes/status.rs +++ b/src/modes/status.rs @@ -20,175 +20,44 @@ use prettytable::format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR; use crate::meta_plugin; use crate::meta_plugin::MetaPluginType; -fn build_path_table(data_path: PathBuf, db_path: PathBuf) -> Table { - let mut path_table = Table::new(); - - if std::io::stdout().is_terminal() { - path_table.set_format(get_format_box_chars_no_border_line_separator()); - } else { - path_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); - } - - path_table.set_titles(Row::new(vec![ - Cell::new("Type").with_style(Attr::Bold), - Cell::new("Path").with_style(Attr::Bold), - ])); - - path_table.add_row(Row::new(vec![ - Cell::new("Data"), - Cell::new( - &data_path - .into_os_string() - .into_string() - .expect("Unable to convert data path to string"), - ), - ])); - - path_table.add_row(Row::new(vec![ - Cell::new("Database"), - Cell::new( - &db_path - .into_os_string() - .into_string() - .expect("Unable to convert DB path to string"), - ), - ])); - - path_table +#[derive(Serialize, Deserialize)] +pub struct StatusInfo { + pub paths: PathInfo, + pub compression: Vec, + pub meta_plugins: Vec, } -fn build_compression_table() -> Table { - let mut compression_table = Table::new(); - if std::io::stdout().is_terminal() { - compression_table.set_format(get_format_box_chars_no_border_line_separator()); - } else { - compression_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); - } - - compression_table.set_titles(row!( - b->"Type", - b->"Found", - b->"Default", - b->"Binary", - b->"Compress", - b->"Decompress")); - - let default_type = compression_engine::default_compression_type(); - - // Sort compression types by their string representation - let mut sorted_compression_types: Vec = CompressionType::iter().collect(); - sorted_compression_types.sort_by_key(|ct| ct.to_string()); - - for compression_type in sorted_compression_types { - let compression_program: CompressionEngineProgram = - match &COMPRESSION_PROGRAMS[compression_type.clone()] { - Some(compression_program) => compression_program.clone(), - None => CompressionEngineProgram { - program: "".to_string(), - compress: Vec::new(), - decompress: Vec::new(), - supported: true, - }, - }; - - let is_default = compression_type == default_type; - - compression_table.add_row(Row::new(vec![ - Cell::new(&compression_type.to_string()), - match compression_program.supported { - true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), - false => Cell::new("No").with_style(Attr::ForegroundColor(color::RED)), - }, - match is_default { - true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), - false => Cell::new("No"), - }, - match compression_program.program.is_empty() { - true => { - Cell::new("").with_style(Attr::ForegroundColor(color::BRIGHT_BLACK)) - } - false => Cell::new(&compression_program.program), - }, - Cell::new(&compression_program.compress.join(" ")), - Cell::new(&compression_program.decompress.join(" ")), - ])); - } - - compression_table +#[derive(Serialize, Deserialize)] +pub struct PathInfo { + pub data: String, + pub database: String, } - -fn build_meta_plugin_table(enabled_meta_plugins: &Vec) -> Table { - let mut meta_plugin_table = Table::new(); - if std::io::stdout().is_terminal() { - meta_plugin_table.set_format(get_format_box_chars_no_border_line_separator()); - } else { - meta_plugin_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); - } - - meta_plugin_table.set_titles(row!( - b->"Meta Name", - b->"Found", - b->"Enabled", - b->"Binary", - b->"Args")); - - // Sort meta plugin types by their meta name - let mut sorted_meta_plugins: Vec = MetaPluginType::iter().collect(); - sorted_meta_plugins.sort_by_key(|meta_plugin_type| { - let mut meta_plugin = meta_plugin::get_meta_plugin(meta_plugin_type.clone()); - meta_plugin.meta_name() - }); - - for meta_plugin_type in sorted_meta_plugins { - let mut meta_plugin = meta_plugin::get_meta_plugin(meta_plugin_type.clone()); - let is_supported = meta_plugin.is_supported(); - let is_enabled = enabled_meta_plugins.contains(&meta_plugin_type); - - // Determine what implementation will actually be used - let (binary_display, args_display) = if !is_supported { - ("".to_string(), "".to_string()) - } else { - if meta_plugin.is_internal() { - ("".to_string(), "".to_string()) - } else { - // Get program info from the meta plugin itself - if let Some((program, args)) = meta_plugin.program_info() { - (program.to_string(), args.join(" ")) - } else { - ("".to_string(), "".to_string()) - } - } - }; - - meta_plugin_table.add_row(Row::new(vec![ - Cell::new(&meta_plugin.meta_name()), - match is_supported { - true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), - false => Cell::new("No").with_style(Attr::ForegroundColor(color::RED)), - }, - match is_enabled { - true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), - false => Cell::new("No"), - }, - match binary_display.as_str() { - "" => Cell::new(&binary_display).with_style(Attr::ForegroundColor(color::BRIGHT_BLACK)), - "" => Cell::new(&binary_display).with_style(Attr::ForegroundColor(color::RED)), - _ => Cell::new(&binary_display), - }, - Cell::new(&args_display), - ])); - } - - meta_plugin_table +#[derive(Serialize, Deserialize)] +pub struct CompressionInfo { + #[serde(rename = "type")] + pub compression_type: String, + pub found: bool, + pub default: bool, + pub binary: String, + pub compress: String, + pub decompress: String, } -fn show_status_structured( +#[derive(Serialize, Deserialize)] +pub struct MetaPluginInfo { + pub meta_name: String, + pub found: bool, + pub enabled: bool, + pub binary: String, + pub args: String, +} + +fn generate_status_info( data_path: PathBuf, db_path: PathBuf, enabled_meta_plugins: &Vec, - output_format: OutputFormat, -) -> Result<(), anyhow::Error> { +) -> StatusInfo { let path_info = PathInfo { data: data_path.into_os_string().into_string().expect("Unable to convert data path to string"), database: db_path.into_os_string().into_string().expect("Unable to convert DB path to string"), @@ -267,61 +136,117 @@ fn show_status_structured( }); } - let status_info = StatusInfo { + StatusInfo { paths: path_info, compression: compression_info, meta_plugins: meta_plugin_info, - }; + } +} - match output_format { - OutputFormat::Json => { - println!("{}", serde_json::to_string_pretty(&status_info)?); - } - OutputFormat::Yaml => { - println!("{}", serde_yaml::to_string(&status_info)?); - } - OutputFormat::Table => unreachable!(), +fn build_path_table(path_info: &PathInfo) -> Table { + let mut path_table = Table::new(); + + if std::io::stdout().is_terminal() { + path_table.set_format(get_format_box_chars_no_border_line_separator()); + } else { + path_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); } - Ok(()) + path_table.set_titles(Row::new(vec![ + Cell::new("Type").with_style(Attr::Bold), + Cell::new("Path").with_style(Attr::Bold), + ])); + + path_table.add_row(Row::new(vec![ + Cell::new("Data"), + Cell::new(&path_info.data), + ])); + + path_table.add_row(Row::new(vec![ + Cell::new("Database"), + Cell::new(&path_info.database), + ])); + + path_table } -#[derive(Serialize, Deserialize)] -pub struct StatusInfo { - pub paths: PathInfo, - pub compression: Vec, - pub meta_plugins: Vec, +fn build_compression_table(compression_info: &Vec) -> Table { + let mut compression_table = Table::new(); + if std::io::stdout().is_terminal() { + compression_table.set_format(get_format_box_chars_no_border_line_separator()); + } else { + compression_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); + } + + compression_table.set_titles(row!( + b->"Type", + b->"Found", + b->"Default", + b->"Binary", + b->"Compress", + b->"Decompress")); + + for info in compression_info { + compression_table.add_row(Row::new(vec![ + Cell::new(&info.compression_type), + match info.found { + true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), + false => Cell::new("No").with_style(Attr::ForegroundColor(color::RED)), + }, + match info.default { + true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), + false => Cell::new("No"), + }, + match info.binary.as_str() { + "" => Cell::new(&info.binary).with_style(Attr::ForegroundColor(color::BRIGHT_BLACK)), + _ => Cell::new(&info.binary), + }, + Cell::new(&info.compress), + Cell::new(&info.decompress), + ])); + } + + compression_table } -#[derive(Serialize, Deserialize)] -pub struct PathInfo { - pub data: String, - pub database: String, +fn build_meta_plugin_table(meta_plugin_info: &Vec) -> Table { + let mut meta_plugin_table = Table::new(); + if std::io::stdout().is_terminal() { + meta_plugin_table.set_format(get_format_box_chars_no_border_line_separator()); + } else { + meta_plugin_table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); + } + + meta_plugin_table.set_titles(row!( + b->"Meta Name", + b->"Found", + b->"Enabled", + b->"Binary", + b->"Args")); + + for info in meta_plugin_info { + meta_plugin_table.add_row(Row::new(vec![ + Cell::new(&info.meta_name), + match info.found { + true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), + false => Cell::new("No").with_style(Attr::ForegroundColor(color::RED)), + }, + match info.enabled { + true => Cell::new("Yes").with_style(Attr::ForegroundColor(color::GREEN)), + false => Cell::new("No"), + }, + match info.binary.as_str() { + "" => Cell::new(&info.binary).with_style(Attr::ForegroundColor(color::BRIGHT_BLACK)), + "" => Cell::new(&info.binary).with_style(Attr::ForegroundColor(color::RED)), + _ => Cell::new(&info.binary), + }, + Cell::new(&info.args), + ])); + } + + meta_plugin_table } -#[derive(Serialize, Deserialize)] -pub struct CompressionInfo { - #[serde(rename = "type")] - pub compression_type: String, - pub found: bool, - pub default: bool, - pub binary: String, - pub compress: String, - pub decompress: String, -} - -#[derive(Serialize, Deserialize)] -pub struct MetaPluginInfo { - pub meta_name: String, - pub found: bool, - pub enabled: bool, - pub binary: String, - pub args: String, -} - - - - pub fn mode_status( _cmd: &mut Command, args: &crate::Args, @@ -346,18 +271,27 @@ pub fn mode_status( } let output_format = get_output_format(args); + let status_info = generate_status_info(data_path, db_path, &meta_plugin_types); - if output_format != OutputFormat::Table { - return show_status_structured(data_path, db_path, &meta_plugin_types, output_format); + match output_format { + OutputFormat::Table => { + println!("PATHS:"); + build_path_table(&status_info.paths).printstd(); + println!(); + println!("COMPRESSION:"); + build_compression_table(&status_info.compression).printstd(); + println!(); + println!("META PLUGINS:"); + build_meta_plugin_table(&status_info.meta_plugins).printstd(); + Ok(()) + }, + OutputFormat::Json => { + println!("{}", serde_json::to_string_pretty(&status_info)?); + Ok(()) + }, + OutputFormat::Yaml => { + println!("{}", serde_yaml::to_string(&status_info)?); + Ok(()) + } } - - println!("PATHS:"); - build_path_table(data_path, db_path).printstd(); - println!(); - println!("COMPRESSION:"); - build_compression_table().printstd(); - println!(); - println!("META PLUGINS:"); - build_meta_plugin_table(&meta_plugin_types).printstd(); - Ok(()) }