diff --git a/src/modes/status.rs b/src/modes/status.rs index 038d473..437d3df 100644 --- a/src/modes/status.rs +++ b/src/modes/status.rs @@ -14,6 +14,8 @@ use prettytable::{Attr, Cell, Row, Table}; use prettytable::format::consts::{FORMAT_NO_BORDER_LINE_SEPARATOR}; use crate::common::status::{PathInfo, CompressionInfo}; +use crate::meta_plugin::MetaPluginType; +use crate::meta_plugin; fn build_path_table(path_info: &PathInfo) -> Table { let mut path_table = Table::new(); @@ -127,6 +129,149 @@ fn build_config_table(settings: &config::Settings) -> Table { config_table } +fn build_meta_plugins_configured_table(settings: &config::Settings) -> Option { + let meta_plugins = settings.meta_plugins.as_ref()?; + if meta_plugins.is_empty() { + return None; + } + + // Sort meta plugins by name + let mut sorted_meta_plugins = meta_plugins.clone(); + sorted_meta_plugins.sort_by(|a, b| a.name.cmp(&b.name)); + + let mut table = Table::new(); + if std::io::stdout().is_terminal() { + table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); + } else { + table.set_format(*FORMAT_NO_BORDER_LINE_SEPARATOR); + } + + table.set_titles(Row::new(vec![ + Cell::new("Plugin Name").with_style(Attr::Bold), + Cell::new("Options").with_style(Attr::Bold), + Cell::new("Outputs").with_style(Attr::Bold), + ])); + + for plugin_config in sorted_meta_plugins { + // Create the plugin to get its default options + let meta_plugin_type = match MetaPluginType::from_str(&plugin_config.name) { + Ok(plugin_type) => plugin_type, + Err(_) => continue, + }; + + // First, create a default plugin to get its default options + let default_plugin = get_meta_plugin( + meta_plugin_type.clone(), + None, + None, + ); + + // Start with the default options + let mut effective_options = default_plugin.options().clone(); + + // Merge with the configured options + for (key, value) in &plugin_config.options { + effective_options.insert(key.clone(), value.clone()); + } + + // Convert outputs from HashMap to HashMap + let outputs_converted: std::collections::HashMap = plugin_config.outputs + .iter() + .map(|(k, v)| (k.clone(), serde_yaml::Value::String(v.clone()))) + .collect(); + + // Create the actual plugin with merged options - the constructor will handle setting up outputs + let actual_plugin = get_meta_plugin( + meta_plugin_type.clone(), + Some(effective_options.clone()), + Some(outputs_converted), + ); + + // Get the default plugin to see its default options + let default_plugin = get_meta_plugin( + meta_plugin_type.clone(), + None, + None, + ); + + // Start with the default options + let mut all_options = default_plugin.options().clone(); + // Merge with the configured options + for (key, value) in &effective_options { + all_options.insert(key.clone(), value.clone()); + } + + // Sort options by key and convert to a YAML string + let mut sorted_options: Vec<_> = all_options.iter().collect(); + sorted_options.sort_by(|a, b| a.0.cmp(b.0)); + let sorted_options_map: std::collections::BTreeMap<_, _> = sorted_options.into_iter().collect(); + + let options_str = if sorted_options_map.is_empty() { + "{}".to_string() + } else { + serde_yaml::to_string(&sorted_options_map) + .unwrap_or_else(|_| "Unable to serialize options".to_string()) + .trim() + .to_string() + }; + + // Show only non-null outputs from the plugin + // Collect and sort outputs by their string representation + let mut enabled_output_pairs = Vec::new(); + for (key, value) in actual_plugin.outputs() { + // Skip null values (disabled outputs) + if value.is_null() { + continue; + } + + // Convert serde_yaml::Value to a string representation + let value_str = match value { + serde_yaml::Value::String(s) => s.clone(), + serde_yaml::Value::Number(n) => n.to_string(), + serde_yaml::Value::Bool(b) => b.to_string(), + serde_yaml::Value::Null => "null".to_string(), + serde_yaml::Value::Sequence(_) => { + serde_yaml::to_string(value).unwrap_or_else(|_| "[]".to_string()) + } + serde_yaml::Value::Mapping(_) => { + serde_yaml::to_string(value).unwrap_or_else(|_| "{}".to_string()) + } + serde_yaml::Value::Tagged(_) => { + serde_yaml::to_string(value).unwrap_or_else(|_| "tagged".to_string()) + } + }; + // Trim any extra whitespace from the serialized values + let value_str = value_str.trim().to_string(); + if key == &value_str { + enabled_output_pairs.push((key.clone(), key.clone())); + } else { + enabled_output_pairs.push((key.clone(), format!("{}->{}", key, value_str))); + } + } + + // Sort outputs by their display value (second element of the tuple) + enabled_output_pairs.sort_by(|a, b| a.1.cmp(&b.1)); + + // Join each output on a new line + let outputs_str = if enabled_output_pairs.is_empty() { + "{}".to_string() + } else { + enabled_output_pairs.into_iter() + .map(|(_, display)| display) + .collect::>() + .join("\n") + }; + + table.add_row(Row::new(vec![ + Cell::new(&plugin_config.name), + Cell::new(&options_str), + Cell::new(&outputs_str), + ])); + } + + Some(table) +} + pub fn mode_status( cmd: &mut Command, @@ -155,6 +300,17 @@ pub fn mode_status( println!("COMPRESSION:"); build_compression_table(&status_info.compression).printstd(); println!(); + + // Always try to print META PLUGINS CONFIGURED section + if let Some(meta_plugins_table) = build_meta_plugins_configured_table(settings) { + println!("META PLUGINS CONFIGURED:"); + meta_plugins_table.printstd(); + println!(); + } else { + println!("META PLUGINS CONFIGURED:"); + println!("No plugins configured"); + println!(); + } Ok(()) }, OutputFormat::Json => { diff --git a/src/modes/status_plugins.rs b/src/modes/status_plugins.rs index 7c2f8a1..07fb9f9 100644 --- a/src/modes/status_plugins.rs +++ b/src/modes/status_plugins.rs @@ -242,17 +242,6 @@ pub fn mode_status_plugins( println!("META PLUGINS AVAILABLE:"); build_meta_plugin_table(&status_info.meta_plugins).printstd(); println!(); - - // Always try to print META PLUGINS CONFIGURED section - if let Some(meta_plugins_table) = build_meta_plugins_configured_table(settings) { - println!("META PLUGINS CONFIGURED:"); - meta_plugins_table.printstd(); - println!(); - } else { - println!("META PLUGINS CONFIGURED:"); - println!("No plugins configured"); - println!(); - } Ok(()) }, OutputFormat::Json => {