diff --git a/src/meta_plugin/digest.rs b/src/meta_plugin/digest.rs index 9264dbc..3d7841e 100644 --- a/src/meta_plugin/digest.rs +++ b/src/meta_plugin/digest.rs @@ -1,6 +1,6 @@ use sha2::{Digest, Sha256, Sha512}; use md5; -use crate::meta_plugin::{MetaPlugin, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginType, BaseMetaPlugin}; use std::io::Write; #[derive(Clone)] @@ -68,8 +68,7 @@ impl Hasher { pub struct DigestMetaPlugin { hasher: Option, is_finalized: bool, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } @@ -78,17 +77,17 @@ impl DigestMetaPlugin { options: Option>, outputs: Option>, ) -> DigestMetaPlugin { - let mut plugin = DigestMetaPlugin::default(); + let mut base = BaseMetaPlugin::new(); // Apply provided options if let Some(opts) = options { for (key, value) in opts { - plugin.options.insert(key, value); + base.options.insert(key, value); } } // Determine the selected method - let method = if let Some(method_value) = plugin.options.get("method") { + let method = if let Some(method_value) = base.options.get("method") { if let Some(method_str) = method_value.as_str() { match method_str { "md5" => "md5", @@ -104,7 +103,7 @@ impl DigestMetaPlugin { }; // Initialize the hasher based on the method - plugin.hasher = match method { + let hasher = match method { "md5" => Some(Hasher::Md5(md5::Context::new())), "sha256" => Some(Hasher::Sha256(Sha256::new())), "sha512" => Some(Hasher::Sha512(Sha512::new())), @@ -112,16 +111,16 @@ impl DigestMetaPlugin { }; // Add the method to options so it shows up in the status - plugin.options.insert("method".to_string(), serde_yaml::Value::String(method.to_string())); + base.options.insert("method".to_string(), serde_yaml::Value::String(method.to_string())); // Set outputs based on the selected hash method // Only the selected method's output should be enabled, others should be None let all_outputs = vec!["digest_md5", "digest_sha256", "digest_sha512"]; - for output_name in all_outputs { - if output_name == format!("digest_{}", method) { - plugin.outputs.insert(output_name.to_string(), serde_yaml::Value::String(output_name.to_string())); + for output_name in &all_outputs { + if output_name == &format!("digest_{}", method) { + base.outputs.insert(output_name.to_string(), serde_yaml::Value::String(output_name.to_string())); } else { - plugin.outputs.insert(output_name.to_string(), serde_yaml::Value::Null); + base.outputs.insert(output_name.to_string(), serde_yaml::Value::Null); } } @@ -129,14 +128,18 @@ impl DigestMetaPlugin { if let Some(outs) = outputs { for (key, value) in outs { // Only update if the output is not disabled (not None) - if let Some(current_value) = plugin.outputs.get_mut(&key) + if let Some(current_value) = base.outputs.get_mut(&key) && !current_value.is_null() { *current_value = value; } } } - plugin + DigestMetaPlugin { + hasher, + is_finalized: false, + base, + } } } @@ -164,21 +167,27 @@ impl MetaPlugin for DigestMetaPlugin { }; } - let metadata = Vec::new(); + let mut metadata = Vec::new(); // Update outputs based on the selected hash method if let Some(hasher) = &mut self.hasher { let hash_value = hasher.finalize(); let output_name = hasher.output_name(); - // Set the selected hash output - self.outputs.insert(output_name.to_string(), serde_yaml::Value::String(hash_value)); + // Use process_metadata_outputs to handle output mapping + if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( + output_name, + serde_yaml::Value::String(hash_value), + self.base.outputs() + ) { + metadata.push(meta_data); + } // Set all other digest outputs to None let all_outputs = vec!["digest_md5", "digest_sha256", "digest_sha512"]; for output_name in all_outputs { if output_name != hasher.output_name() { - self.outputs.insert(output_name.to_string(), serde_yaml::Value::Null); + self.base.outputs.insert(output_name.to_string(), serde_yaml::Value::Null); } } } @@ -214,11 +223,11 @@ impl MetaPlugin for DigestMetaPlugin { } fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } fn default_outputs(&self) -> Vec { @@ -229,13 +238,12 @@ impl MetaPlugin for DigestMetaPlugin { ] } - fn options(&self) -> &std::collections::HashMap { - &self.options + self.base.options() } fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options + self.base.options_mut() } } @@ -247,4 +255,4 @@ fn register_digest_plugin() { register_meta_plugin(MetaPluginType::Digest, |options, outputs| { Box::new(DigestMetaPlugin::new(options, outputs)) }); -} \ No newline at end of file +} diff --git a/src/meta_plugin/env.rs b/src/meta_plugin/env.rs index d6bbe68..ad81c26 100644 --- a/src/meta_plugin/env.rs +++ b/src/meta_plugin/env.rs @@ -1,10 +1,10 @@ -use super::{MetaPlugin, MetaPluginType, process_metadata_outputs}; +use super::{MetaPlugin, MetaPluginType, process_metadata_outputs, BaseMetaPlugin}; #[derive(Debug, Clone)] /// Meta plugin that extracts environment variables prefixed with KEEP_META_ as metadata. pub struct EnvMetaPlugin { is_finalized: bool, - outputs: std::collections::HashMap, + base: BaseMetaPlugin, env_vars: Vec<(String, String)>, } @@ -48,9 +48,12 @@ impl EnvMetaPlugin { } } + let mut base = BaseMetaPlugin::new(); + base.outputs = outputs_map; + EnvMetaPlugin { is_finalized: false, - outputs: outputs_map, + base, env_vars, } } @@ -106,7 +109,7 @@ impl MetaPlugin for EnvMetaPlugin { if let Some(meta_data) = process_metadata_outputs( name, serde_yaml::Value::String(value.clone()), - &self.outputs + self.base.outputs() ) { metadata.push(meta_data); } @@ -172,7 +175,7 @@ impl MetaPlugin for EnvMetaPlugin { /// /// A reference to the `HashMap` of outputs. fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } /// Returns a mutable reference to the outputs mapping. @@ -181,7 +184,7 @@ impl MetaPlugin for EnvMetaPlugin { /// /// A mutable reference to the `HashMap` of outputs. fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } /// Returns the default output names based on collected env vars. @@ -203,10 +206,7 @@ impl MetaPlugin for EnvMetaPlugin { /// /// An empty `HashMap`. fn options(&self) -> &std::collections::HashMap { - use once_cell::sync::Lazy; - static EMPTY: Lazy> = - Lazy::new(std::collections::HashMap::new); - &EMPTY + self.base.options() } /// Returns a mutable reference to the options mapping. @@ -215,7 +215,7 @@ impl MetaPlugin for EnvMetaPlugin { /// /// Panics with "options_mut() not implemented for EnvMetaPlugin". fn options_mut(&mut self) -> &mut std::collections::HashMap { - panic!("options_mut() not implemented for EnvMetaPlugin") + self.base.options_mut() } } use crate::meta_plugin::register_meta_plugin; @@ -226,4 +226,4 @@ fn register_env_plugin() { register_meta_plugin(MetaPluginType::Env, |options, outputs| { Box::new(EnvMetaPlugin::new(options, outputs)) }); -} \ No newline at end of file +} diff --git a/src/meta_plugin/exec.rs b/src/meta_plugin/exec.rs index ad81920..03adc5b 100644 --- a/src/meta_plugin/exec.rs +++ b/src/meta_plugin/exec.rs @@ -3,7 +3,7 @@ use std::io::Write; use std::process::{Command, Stdio, Child}; use which::which; -use crate::meta_plugin::{MetaPlugin, MetaPluginResponse, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginResponse, MetaPluginType, BaseMetaPlugin}; /// External program execution meta plugin. /// @@ -22,8 +22,7 @@ pub struct MetaPluginExec { process: Option, writer: Option>, result: Option, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } // Manual Debug implementation because Box doesn't implement Debug @@ -40,8 +39,7 @@ impl std::fmt::Debug for MetaPluginExec { .field("process", &self.process) .field("writer", &self.writer.as_ref().map(|_| "Box")) .field("result", &self.result) - .field("outputs", &self.outputs) - .field("options", &self.options) + .field("base", &self.base) .finish() } } @@ -69,337 +67,4 @@ impl MetaPluginExec { /// # Examples /// /// ``` - /// let plugin = MetaPluginExec::new("date", vec![], "timestamp", false, None, None); - /// assert!(plugin.supported); // If 'date' is available - /// ``` - pub fn new( - program: &str, - args: Vec<&str>, - meta_name: String, - split_whitespace: bool, - _options: Option>, - outputs: Option>, - ) -> MetaPluginExec { - let program_path = which(program); - let supported = program_path.is_ok(); - - // Start with default outputs - let mut final_outputs = std::collections::HashMap::new(); - final_outputs.insert(meta_name.clone(), serde_yaml::Value::String(meta_name.clone())); - if let Some(outs) = outputs { - for (key, value) in outs { - final_outputs.insert(key, value); - } - } - - // Start with default options - let mut final_options = std::collections::HashMap::new(); - if let Some(opts) = _options { - for (key, value) in opts { - final_options.insert(key, value); - } - } - - MetaPluginExec { - program: program_path.map_or_else(|_| program.to_string(), |p| p.to_string_lossy().to_string()), - args: args.iter().map(|s| s.to_string()).collect(), - supported, - split_whitespace, - process: None, - writer: None, - result: None, - outputs: final_outputs, - options: final_options, - } - } - -} - -impl MetaPlugin for MetaPluginExec { - /// Checks if the external program is available on the system. - /// - /// # Returns - /// - /// * `bool` - True if the program was found via `which`. - fn is_supported(&self) -> bool { - self.supported - } - - /// Indicates if this is an internal (built-in) plugin. - /// - /// External exec plugins are always non-internal. - /// - /// # Returns - /// - /// * `false` - Always false for this plugin type. - fn is_internal(&self) -> bool { - false - } - - /// Initializes the plugin by spawning the external process. - /// - /// Sets up piped stdin/stdout/stderr for the command. Does not finalize yet. - /// - /// # Returns - /// - /// * `MetaPluginResponse` - Empty metadata, not finalized. - /// - /// # Errors - /// - /// If spawn fails, returns finalized response with no metadata (logs error). - /// - /// # Examples - /// - /// ``` - /// let mut plugin = MetaPluginExec::new("echo", vec!["hello"], "output", false, None, None); - /// let response = plugin.initialize(); - /// assert!(!response.is_finalized); - /// ``` - fn initialize(&mut self) -> MetaPluginResponse { - debug!("META: Initializing program plugin: {:?}", self); - - let program = self.program.clone(); - let args = self.args.clone(); - - debug!("META: Executing command: {:?} {:?}", program, args); - - let mut process = match Command::new(program.clone()) - .args(args.clone()) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - { - Ok(process) => process, - Err(e) => { - debug!("META: Failed to spawn process: {}", e); - return MetaPluginResponse { - metadata: Vec::new(), - is_finalized: true, - }; - } - }; - - let stdin = process.stdin.take().unwrap(); - self.writer = Some(Box::new(stdin)); - self.process = Some(process); - - MetaPluginResponse { - metadata: Vec::new(), - is_finalized: false, - } - } - - /// Finalizes the plugin by waiting for the process to complete and capturing output. - /// - /// Processes stdout based on split_whitespace option, adds to metadata if successful. - /// Logs stderr and status on failure but does not propagate as error. - /// - /// # Returns - /// - /// * `MetaPluginResponse` - Metadata from output (if any), always finalized. - /// - /// # Examples - /// - /// ``` - /// let response = plugin.finalize(); - /// assert!(response.is_finalized); - /// if let Some(meta) = response.metadata.first() { - /// // Contains captured output - /// } - /// ``` - fn finalize(&mut self) -> MetaPluginResponse { - debug!("META: Finalizing program plugin"); - let mut metadata = Vec::new(); - - if let Some(process) = self.process.take() { - // Close stdin to signal end of input - drop(self.writer.take()); - - // Wait for the process to complete - let output = match process.wait_with_output() { - Ok(output) => output, - Err(e) => { - debug!("META: Failed to get process output: {}", e); - return MetaPluginResponse { - metadata: Vec::new(), - is_finalized: true, - }; - } - }; - - if output.status.success() { - // Process the output - let output_str = String::from_utf8_lossy(&output.stdout); - let result = if self.split_whitespace { - output_str.split_whitespace().next().unwrap_or("").to_string() - } else { - output_str.trim().to_string() - }; - - if !result.is_empty() { - debug!("META: Program output: {}", result); - self.result = Some(result.clone()); - - // Use process_metadata_outputs to handle output mapping - if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( - &self.meta_type().to_string(), - serde_yaml::Value::String(result), - &self.outputs - ) { - metadata.push(meta_data); - } - } - } else { - debug!("META: Program failed with status: {:?}", output.status); - let stderr = String::from_utf8_lossy(&output.stderr); - if !stderr.is_empty() { - debug!("META: Program stderr: {}", stderr); - } - } - } - - MetaPluginResponse { - metadata, - is_finalized: true, - } - } - - /// Updates the plugin by writing data to the process's stdin. - /// - /// Pipes incoming data (e.g., item content) to the command for processing. - /// Logs write errors but continues. - /// - /// # Arguments - /// - /// * `data` - Byte slice to write to stdin. - /// - /// # Returns - /// - /// * `MetaPluginResponse` - Empty metadata, not finalized. - fn update(&mut self, data: &[u8]) -> MetaPluginResponse { - if let Some(ref mut writer) = self.writer - && let Err(e) = writer.write_all(data) { - debug!("META: Failed to write to process stdin: {}", e); - } - MetaPluginResponse { - metadata: Vec::new(), - is_finalized: false, - } - } - - /// Returns the type of this meta plugin. - /// - /// # Returns - /// - /// * `MetaPluginType::Exec` - The exec plugin type. - fn meta_type(&self) -> MetaPluginType { - MetaPluginType::Exec - } - - /// Provides information about the program and its arguments. - /// - /// Only returns data if the program is supported. - /// - /// # Returns - /// - /// * `Option<(&str, Vec<&str>)>` - Tuple of program path and arg slices, or None. - fn program_info(&self) -> Option<(&str, Vec<&str>)> { - if self.supported { - Some((&self.program, self.args.iter().map(|s| s.as_str()).collect())) - } else { - None - } - } - - /// Returns an immutable reference to the plugin's outputs. - /// - /// # Returns - /// - /// * `&HashMap` - The outputs map. - fn outputs(&self) -> &std::collections::HashMap { - &self.outputs - } - - /// Returns a mutable reference to the plugin's outputs. - /// - /// # Returns - /// - /// * `&mut HashMap` - Mutable outputs map. - fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs - } - - /// Returns the default output keys for this plugin. - /// - /// # Returns - /// - /// * `Vec` - Vector with the exec type string. - fn default_outputs(&self) -> Vec { - vec![self.meta_type().to_string()] - } - - - /// Returns an immutable reference to the plugin's options. - /// - /// # Returns - /// - /// * `&HashMap` - The options map. - fn options(&self) -> &std::collections::HashMap { - &self.options - } - - /// Returns a mutable reference to the plugin's options. - /// - /// # Returns - /// - /// * `&mut HashMap` - Mutable options map. - fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options - } -} -/// Registers the exec meta plugin with the global registry. -/// -/// This constructor function is called at module load time using ctor crate. -/// It parses "command" option for program/args, "split_whitespace" for output processing, -/// and "name" for metadata key. Falls back to defaults if missing. -use crate::meta_plugin::register_meta_plugin; - -// Register the plugin at module initialization time -#[ctor::ctor] -fn register_exec_plugin() { - register_meta_plugin(MetaPluginType::Exec, |options, outputs| { - // For exec type, we need to parse the command from options - let mut program_name = String::new(); - let mut args = Vec::new(); - let mut meta_name = MetaPluginType::Exec.to_string(); - let mut split_whitespace = true; - - if let Some(opts) = &options { - if let Some(command_value) = opts.get("command") - && let Some(command_str) = command_value.as_str() { - let parts: Vec<&str> = command_str.split_whitespace().collect(); - if !parts.is_empty() { - program_name = parts[0].to_string(); - args = parts[1..].iter().map(|s| s.to_string()).collect(); - } - } - // Handle other options if needed - if let Some(split_value) = opts.get("split_whitespace") - && let Some(split_bool) = split_value.as_bool() { - split_whitespace = split_bool; - } - if let Some(name_value) = opts.get("name") - && let Some(name_str) = name_value.as_str() { - meta_name = name_str.to_string(); - } - } - - Box::new(MetaPluginExec::new(&program_name, - args.iter().map(|s| s.as_str()).collect(), - meta_name, - split_whitespace, - options, - outputs)) - }); -} \ No newline at end of file + /// let plugin \ No newline at end of file diff --git a/src/meta_plugin/keep_pid.rs b/src/meta_plugin/keep_pid.rs index 32df81e..2280631 100644 --- a/src/meta_plugin/keep_pid.rs +++ b/src/meta_plugin/keep_pid.rs @@ -1,11 +1,10 @@ use std::process; -use crate::meta_plugin::{MetaPlugin, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginType, BaseMetaPlugin}; #[derive(Debug, Clone, Default)] pub struct KeepPidMetaPlugin { is_finalized: bool, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } impl KeepPidMetaPlugin { @@ -23,30 +22,15 @@ impl KeepPidMetaPlugin { _options: Option>, outputs: Option>, ) -> KeepPidMetaPlugin { - // Start with default options - let mut final_options = std::collections::HashMap::new(); - if let Some(opts) = _options { - for (key, value) in opts { - final_options.insert(key, value); - } - } + let mut base = BaseMetaPlugin::new(); - // Start with default outputs - let mut final_outputs = std::collections::HashMap::new(); - let default_outputs = Self::default().default_outputs(); - for output_name in default_outputs { - final_outputs.insert(output_name.clone(), serde_yaml::Value::String(output_name)); - } - if let Some(outs) = outputs { - for (key, value) in outs { - final_outputs.insert(key, value); - } - } + // Set default outputs + let default_outputs = &["keep_pid"]; + base.initialize_plugin(default_outputs, _options, outputs); KeepPidMetaPlugin { is_finalized: false, - outputs: final_outputs, - options: final_options, + base, } } @@ -127,13 +111,51 @@ impl MetaPlugin for KeepPidMetaPlugin { MetaPluginType::KeepPid } + /// Initializes the plugin and captures the process PID. + /// + /// Retrieves the current process ID and adds it to metadata. + /// Marks the plugin as finalized after one run. + /// + /// # Returns + /// + /// * `MetaPluginResponse` - Response with PID metadata and finalized state. + fn initialize(&mut self) -> crate::meta_plugin::MetaPluginResponse { + // If already finalized, don't process again + if self.is_finalized { + return crate::meta_plugin::MetaPluginResponse { + metadata: Vec::new(), + is_finalized: true, + }; + } + + let mut metadata = Vec::new(); + let pid = process::id().to_string(); + + // Use process_metadata_outputs to handle output mapping + if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( + "keep_pid", + serde_yaml::Value::String(pid), + self.base.outputs() + ) { + metadata.push(meta_data); + } + + // Mark as finalized since this plugin only needs to run once + self.is_finalized = true; + + crate::meta_plugin::MetaPluginResponse { + metadata, + is_finalized: true, + } + } + /// Returns a reference to the outputs mapping. /// /// # Returns /// /// A reference to the `HashMap` of outputs. fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } /// Returns a mutable reference to the outputs mapping. @@ -142,10 +164,17 @@ impl MetaPlugin for KeepPidMetaPlugin { /// /// A mutable reference to the `HashMap` of outputs. fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } - + /// Returns the default output names for this plugin. + /// + /// # Returns + /// + /// Vector containing "keep_pid". + fn default_outputs(&self) -> Vec { + vec!["keep_pid".to_string()] + } /// Returns a reference to the options mapping. /// @@ -153,7 +182,7 @@ impl MetaPlugin for KeepPidMetaPlugin { /// /// A reference to the `HashMap` of options. fn options(&self) -> &std::collections::HashMap { - &self.options + self.base.options() } /// Returns a mutable reference to the options mapping. @@ -162,7 +191,7 @@ impl MetaPlugin for KeepPidMetaPlugin { /// /// A mutable reference to the `HashMap` of options. fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options + self.base.options_mut() } } use crate::meta_plugin::register_meta_plugin; diff --git a/src/meta_plugin/read_rate.rs b/src/meta_plugin/read_rate.rs index 9e6c32a..dc714ab 100644 --- a/src/meta_plugin/read_rate.rs +++ b/src/meta_plugin/read_rate.rs @@ -1,6 +1,6 @@ use std::time::Instant; -use crate::meta_plugin::{MetaPlugin, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginType, BaseMetaPlugin}; #[derive(Debug, Clone, Default)] /// Meta plugin that calculates the read rate (KB/s) of input data. @@ -14,14 +14,12 @@ use crate::meta_plugin::{MetaPlugin, MetaPluginType}; /// * `start_time` - Start time of reading, if begun. /// * `bytes_read` - Total bytes accumulated. /// * `is_finalized` - Whether processing is complete. -/// * `outputs` - Mapping of output names to values. -/// * `options` - Configuration options. +/// * `base` - Base plugin for outputs and options. pub struct ReadRateMetaPlugin { start_time: Option, bytes_read: u64, is_finalized: bool, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } impl ReadRateMetaPlugin { @@ -49,32 +47,17 @@ impl ReadRateMetaPlugin { _options: Option>, outputs: Option>, ) -> ReadRateMetaPlugin { - // Start with default options - let mut final_options = std::collections::HashMap::new(); - if let Some(opts) = _options { - for (key, value) in opts { - final_options.insert(key, value); - } - } + let mut base = BaseMetaPlugin::new(); - // Start with default outputs - let mut final_outputs = std::collections::HashMap::new(); - let default_outputs = Self::default().default_outputs(); - for output_name in default_outputs { - final_outputs.insert(output_name.clone(), serde_yaml::Value::String(output_name)); - } - if let Some(outs) = outputs { - for (key, value) in outs { - final_outputs.insert(key, value); - } - } + // Set default outputs + let default_outputs = &["read_rate"]; + base.initialize_plugin(default_outputs, _options, outputs); ReadRateMetaPlugin { start_time: None, bytes_read: 0, is_finalized: false, - outputs: final_outputs, - options: final_options, + base, } } @@ -136,7 +119,7 @@ impl MetaPlugin for ReadRateMetaPlugin { if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "read_rate", serde_yaml::Value::String(rate), - &self.outputs + self.base.outputs() ) { metadata.push(meta_data); } @@ -197,7 +180,7 @@ impl MetaPlugin for ReadRateMetaPlugin { /// /// Immutable reference to the outputs HashMap. fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } /// Returns a mutable reference to the outputs mapping. @@ -208,10 +191,17 @@ impl MetaPlugin for ReadRateMetaPlugin { /// /// Mutable reference to the outputs HashMap. fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } - + /// Returns the default output names for this plugin. + /// + /// # Returns + /// + /// Vector containing "read_rate". + fn default_outputs(&self) -> Vec { + vec!["read_rate".to_string()] + } /// Returns a reference to the options mapping. /// @@ -219,7 +209,7 @@ impl MetaPlugin for ReadRateMetaPlugin { /// /// Immutable reference to the options HashMap. fn options(&self) -> &std::collections::HashMap { - &self.options + self.base.options() } /// Returns a mutable reference to the options mapping. @@ -230,7 +220,7 @@ impl MetaPlugin for ReadRateMetaPlugin { /// /// Mutable reference to the options HashMap. fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options + self.base.options_mut() } } use crate::meta_plugin::register_meta_plugin; diff --git a/src/meta_plugin/read_time.rs b/src/meta_plugin/read_time.rs index 0f66a69..504cfe0 100644 --- a/src/meta_plugin/read_time.rs +++ b/src/meta_plugin/read_time.rs @@ -1,13 +1,12 @@ use std::time::Instant; -use crate::meta_plugin::{MetaPlugin, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginType, BaseMetaPlugin}; #[derive(Debug, Clone, Default)] pub struct ReadTimeMetaPlugin { start_time: Option, is_finalized: bool, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } impl ReadTimeMetaPlugin { @@ -15,31 +14,16 @@ impl ReadTimeMetaPlugin { _options: Option>, outputs: Option>, ) -> ReadTimeMetaPlugin { - // Start with default options - let mut final_options = std::collections::HashMap::new(); - if let Some(opts) = _options { - for (key, value) in opts { - final_options.insert(key, value); - } - } + let mut base = BaseMetaPlugin::new(); - // Start with default outputs - let mut final_outputs = std::collections::HashMap::new(); - let default_outputs = Self::default().default_outputs(); - for output_name in default_outputs { - final_outputs.insert(output_name.clone(), serde_yaml::Value::String(output_name)); - } - if let Some(outs) = outputs { - for (key, value) in outs { - final_outputs.insert(key, value); - } - } + // Set default outputs + let default_outputs = &["read_time"]; + base.initialize_plugin(default_outputs, _options, outputs); ReadTimeMetaPlugin { start_time: None, is_finalized: false, - outputs: final_outputs, - options: final_options, + base, } } @@ -73,7 +57,7 @@ impl MetaPlugin for ReadTimeMetaPlugin { if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "read_time", serde_yaml::Value::String(duration_str), - &self.outputs + self.base.outputs() ) { metadata.push(meta_data); } @@ -111,21 +95,23 @@ impl MetaPlugin for ReadTimeMetaPlugin { } fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } - + fn default_outputs(&self) -> Vec { + vec!["read_time".to_string()] + } fn options(&self) -> &std::collections::HashMap { - &self.options + self.base.options() } fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options + self.base.options_mut() } } use crate::meta_plugin::register_meta_plugin; diff --git a/src/meta_plugin/shell.rs b/src/meta_plugin/shell.rs index ea1cf42..5daf2de 100644 --- a/src/meta_plugin/shell.rs +++ b/src/meta_plugin/shell.rs @@ -1,6 +1,6 @@ use std::env; -use crate::meta_plugin::{MetaPlugin, MetaPluginType}; +use crate::meta_plugin::{MetaPlugin, MetaPluginType, BaseMetaPlugin}; #[derive(Debug, Clone, Default)] /// Meta plugin for capturing shell environment information. @@ -10,8 +10,7 @@ use crate::meta_plugin::{MetaPlugin, MetaPluginType}; /// process input data. pub struct ShellMetaPlugin { is_finalized: bool, - outputs: std::collections::HashMap, - options: std::collections::HashMap, + base: BaseMetaPlugin, } impl ShellMetaPlugin { @@ -38,30 +37,15 @@ impl ShellMetaPlugin { _options: Option>, outputs: Option>, ) -> ShellMetaPlugin { - // Start with default options - let mut final_options = std::collections::HashMap::new(); - if let Some(opts) = _options { - for (key, value) in opts { - final_options.insert(key, value); - } - } + let mut base = BaseMetaPlugin::new(); - // Start with default outputs - let mut final_outputs = std::collections::HashMap::new(); - let default_outputs = Self::default().default_outputs(); - for output_name in default_outputs { - final_outputs.insert(output_name.clone(), serde_yaml::Value::String(output_name)); - } - if let Some(outs) = outputs { - for (key, value) in outs { - final_outputs.insert(key, value); - } - } + // Set default outputs + let default_outputs = &["shell"]; + base.initialize_plugin(default_outputs, _options, outputs); ShellMetaPlugin { is_finalized: false, - outputs: final_outputs, - options: final_options, + base, } } @@ -181,7 +165,7 @@ impl MetaPlugin for ShellMetaPlugin { if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "shell", serde_yaml::Value::String(shell), - &self.outputs + self.base.outputs() ) { metadata.push(meta_data); } @@ -201,7 +185,7 @@ impl MetaPlugin for ShellMetaPlugin { /// /// * `&HashMap` - The outputs map. fn outputs(&self) -> &std::collections::HashMap { - &self.outputs + self.base.outputs() } /// Returns a mutable reference to the plugin's outputs. @@ -210,10 +194,17 @@ impl MetaPlugin for ShellMetaPlugin { /// /// * `&mut HashMap` - Mutable outputs map. fn outputs_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.outputs + self.base.outputs_mut() } - + /// Returns the default output names for this plugin. + /// + /// # Returns + /// + /// Vector containing "shell". + fn default_outputs(&self) -> Vec { + vec!["shell".to_string()] + } /// Returns a reference to the plugin's options. /// @@ -221,7 +212,7 @@ impl MetaPlugin for ShellMetaPlugin { /// /// * `&HashMap` - The options map. fn options(&self) -> &std::collections::HashMap { - &self.options + self.base.options() } /// Returns a mutable reference to the plugin's options. @@ -230,7 +221,7 @@ impl MetaPlugin for ShellMetaPlugin { /// /// * `&mut HashMap` - Mutable options map. fn options_mut(&mut self) -> &mut std::collections::HashMap { - &mut self.options + self.base.options_mut() } } /// Registers the shell meta plugin with the global registry.