From 81397c1319c9d84f60775b2a4266092c6e4ae00d Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Tue, 19 Aug 2025 13:56:33 -0300 Subject: [PATCH] feat: update meta plugin constructors to accept options and outputs Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) --- src/meta_plugin.rs | 42 +++---- src/meta_plugin/binary.rs | 37 +++++- src/meta_plugin/digest.rs | 72 ++++++++++- src/meta_plugin/magic.rs | 38 +++++- src/meta_plugin/program.rs | 25 +++- src/meta_plugin/system.rs | 240 +++++++++++++++++++++++++++++++++---- 6 files changed, 399 insertions(+), 55 deletions(-) diff --git a/src/meta_plugin.rs b/src/meta_plugin.rs index e519a47..f7e5aea 100644 --- a/src/meta_plugin.rs +++ b/src/meta_plugin.rs @@ -145,26 +145,26 @@ pub trait MetaPlugin { pub fn get_meta_plugin(meta_plugin_type: MetaPluginType) -> Box { match meta_plugin_type { - MetaPluginType::FileMagic => Box::new(MetaPluginProgram::new("file", vec!["-bE", "-"], "file_magic".to_string(), true)), - MetaPluginType::FileMime => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-type", "-"], "file_mime".to_string(), true)), - MetaPluginType::FileEncoding => Box::new(MetaPluginProgram::new("file", vec!["-b", "--mime-encoding", "-"], "file_encoding".to_string(), true)), - MetaPluginType::MagicFile => Box::new(MagicFileMetaPlugin::new()), - MetaPluginType::LineCount => Box::new(MetaPluginProgram::new("wc", vec!["-l"], "line_count".to_string(), true)), - MetaPluginType::WordCount => Box::new(MetaPluginProgram::new("wc", vec!["-w"], "word_count".to_string(), true)), - MetaPluginType::Cwd => Box::new(CwdMetaPlugin::new()), - MetaPluginType::Binary => Box::new(BinaryMetaPlugin::new()), - MetaPluginType::Uid => Box::new(UidMetaPlugin::new()), - MetaPluginType::User => Box::new(UserMetaPlugin::new()), - MetaPluginType::Gid => Box::new(GidMetaPlugin::new()), - MetaPluginType::Group => Box::new(GroupMetaPlugin::new()), - MetaPluginType::Shell => Box::new(ShellMetaPlugin::new()), - MetaPluginType::ShellPid => Box::new(ShellPidMetaPlugin::new()), - MetaPluginType::KeepPid => Box::new(KeepPidMetaPlugin::new()), - MetaPluginType::DigestSha256 => Box::new(DigestSha256MetaPlugin::new()), - MetaPluginType::DigestMd5 => Box::new(MetaPluginProgram::new("md5sum", vec![], "digest_md5".to_string(), true)), - MetaPluginType::ReadTime => Box::new(ReadTimeMetaPlugin::new()), - MetaPluginType::ReadRate => Box::new(ReadRateMetaPlugin::new()), - MetaPluginType::Hostname => Box::new(HostnameMetaPlugin::new()), - MetaPluginType::FullHostname => Box::new(FullHostnameMetaPlugin::new()), + MetaPluginType::FileMagic => Box::new(MetaPluginProgram::new_simple("file", vec!["-bE", "-"], "file_magic".to_string(), true)), + MetaPluginType::FileMime => Box::new(MetaPluginProgram::new_simple("file", vec!["-b", "--mime-type", "-"], "file_mime".to_string(), true)), + MetaPluginType::FileEncoding => Box::new(MetaPluginProgram::new_simple("file", vec!["-b", "--mime-encoding", "-"], "file_encoding".to_string(), true)), + MetaPluginType::MagicFile => Box::new(MagicFileMetaPlugin::new_simple()), + MetaPluginType::LineCount => Box::new(MetaPluginProgram::new_simple("wc", vec!["-l"], "line_count".to_string(), true)), + MetaPluginType::WordCount => Box::new(MetaPluginProgram::new_simple("wc", vec!["-w"], "word_count".to_string(), true)), + MetaPluginType::Cwd => Box::new(CwdMetaPlugin::new_simple()), + MetaPluginType::Binary => Box::new(BinaryMetaPlugin::new_simple()), + MetaPluginType::Uid => Box::new(UidMetaPlugin::new_simple()), + MetaPluginType::User => Box::new(UserMetaPlugin::new_simple()), + MetaPluginType::Gid => Box::new(GidMetaPlugin::new_simple()), + MetaPluginType::Group => Box::new(GroupMetaPlugin::new_simple()), + MetaPluginType::Shell => Box::new(ShellMetaPlugin::new_simple()), + MetaPluginType::ShellPid => Box::new(ShellPidMetaPlugin::new_simple()), + MetaPluginType::KeepPid => Box::new(KeepPidMetaPlugin::new_simple()), + MetaPluginType::DigestSha256 => Box::new(DigestSha256MetaPlugin::new_simple()), + MetaPluginType::DigestMd5 => Box::new(MetaPluginProgram::new_simple("md5sum", vec![], "digest_md5".to_string(), true)), + MetaPluginType::ReadTime => Box::new(ReadTimeMetaPlugin::new_simple()), + MetaPluginType::ReadRate => Box::new(ReadRateMetaPlugin::new_simple()), + MetaPluginType::Hostname => Box::new(HostnameMetaPlugin::new_simple()), + MetaPluginType::FullHostname => Box::new(FullHostnameMetaPlugin::new_simple()), } } diff --git a/src/meta_plugin/binary.rs b/src/meta_plugin/binary.rs index 62d1537..9a898cd 100644 --- a/src/meta_plugin/binary.rs +++ b/src/meta_plugin/binary.rs @@ -15,17 +15,48 @@ pub struct BinaryMetaPlugin { } impl BinaryMetaPlugin { - pub fn new() -> BinaryMetaPlugin { + pub fn new( + options: Option>, + outputs: Option>, + ) -> BinaryMetaPlugin { + // Start with default options + let mut final_options = Self::default_options(); + if let Some(opts) = options { + for (key, value) in opts { + final_options.insert(key, value); + } + } + + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + + let max_buffer_size = final_options.get("max_buffer_size") + .and_then(|v| v.as_u64()) + .unwrap_or(4096) as usize; + BinaryMetaPlugin { meta_name: "binary".to_string(), buffer: Vec::new(), - max_buffer_size: 4096, // 4KB + max_buffer_size, is_saved: false, item_id: None, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + pub fn new_simple() -> BinaryMetaPlugin { + Self::new(None, None) + } + fn save_metadata(&mut self, conn: &Connection) -> Result<()> { if !self.is_saved { if let Some(item_id) = self.item_id { diff --git a/src/meta_plugin/digest.rs b/src/meta_plugin/digest.rs index addddb0..6232dc7 100644 --- a/src/meta_plugin/digest.rs +++ b/src/meta_plugin/digest.rs @@ -14,14 +14,34 @@ pub struct DigestSha256MetaPlugin { } impl DigestSha256MetaPlugin { - pub fn new() -> DigestSha256MetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> DigestSha256MetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + DigestSha256MetaPlugin { hasher: Sha256::new(), meta_name: "digest_sha256".to_string(), item_id: None, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> DigestSha256MetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for DigestSha256MetaPlugin { @@ -80,13 +100,33 @@ pub struct ReadTimeMetaPlugin { } impl ReadTimeMetaPlugin { - pub fn new() -> ReadTimeMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> ReadTimeMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + ReadTimeMetaPlugin { start_time: None, meta_name: "read_time".to_string(), - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> ReadTimeMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for ReadTimeMetaPlugin { @@ -134,14 +174,34 @@ pub struct ReadRateMetaPlugin { } impl ReadRateMetaPlugin { - pub fn new() -> ReadRateMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> ReadRateMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + ReadRateMetaPlugin { start_time: None, bytes_read: 0, meta_name: "read_rate".to_string(), - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> ReadRateMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for ReadRateMetaPlugin { diff --git a/src/meta_plugin/magic.rs b/src/meta_plugin/magic.rs index 7c37072..98d045c 100644 --- a/src/meta_plugin/magic.rs +++ b/src/meta_plugin/magic.rs @@ -16,16 +16,48 @@ pub struct MagicFileMetaPlugin { } impl MagicFileMetaPlugin { - pub fn new() -> MagicFileMetaPlugin { + pub fn new( + options: Option>, + outputs: Option>, + ) -> MagicFileMetaPlugin { + // Start with default options + let mut final_options = Self::default_options(); + if let Some(opts) = options { + for (key, value) in opts { + final_options.insert(key, value); + } + } + + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + + let max_buffer_size = final_options.get("max_buffer_size") + .and_then(|v| v.as_u64()) + .unwrap_or(4096) as usize; + MagicFileMetaPlugin { buffer: Vec::new(), - max_buffer_size: 4096, // Same as BinaryMetaPlugin + max_buffer_size, is_saved: false, item_id: None, cookie: None, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> MagicFileMetaPlugin { + Self::new(None, None) + } +} fn get_magic_result(&self, flags: CookieFlags) -> io::Result { // Use the existing cookie and just change flags diff --git a/src/meta_plugin/program.rs b/src/meta_plugin/program.rs index 9df71b4..e71233b 100644 --- a/src/meta_plugin/program.rs +++ b/src/meta_plugin/program.rs @@ -36,9 +36,25 @@ impl std::fmt::Debug for MetaPluginProgram { } impl MetaPluginProgram { - pub fn new(program: &str, args: Vec<&str>, meta_name: String, split_whitespace: bool) -> MetaPluginProgram { + pub fn new( + program: &str, + args: Vec<&str>, + meta_name: String, + split_whitespace: bool, + options: Option>, + outputs: Option>, + ) -> MetaPluginProgram { 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); + } + } MetaPluginProgram { program: program_path.map_or_else(|_| program.to_string(), |p| p.to_string_lossy().to_string()), @@ -50,9 +66,14 @@ impl MetaPluginProgram { writer: None, item_id: None, result: None, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple(program: &str, args: Vec<&str>, meta_name: String, split_whitespace: bool) -> MetaPluginProgram { + Self::new(program, args, meta_name, split_whitespace, None, None) + } +} } impl MetaPlugin for MetaPluginProgram { diff --git a/src/meta_plugin/system.rs b/src/meta_plugin/system.rs index e765524..c6148cf 100644 --- a/src/meta_plugin/system.rs +++ b/src/meta_plugin/system.rs @@ -17,13 +17,33 @@ pub struct CwdMetaPlugin { } impl CwdMetaPlugin { - pub fn new() -> CwdMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> CwdMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + CwdMetaPlugin { meta_name: "cwd".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> CwdMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for CwdMetaPlugin { @@ -80,13 +100,33 @@ pub struct UidMetaPlugin { } impl UidMetaPlugin { - pub fn new() -> UidMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> UidMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + UidMetaPlugin { meta_name: "uid".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> UidMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for UidMetaPlugin { @@ -139,13 +179,33 @@ pub struct UserMetaPlugin { } impl UserMetaPlugin { - pub fn new() -> UserMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> UserMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + UserMetaPlugin { meta_name: "user".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> UserMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for UserMetaPlugin { @@ -201,13 +261,33 @@ pub struct GidMetaPlugin { } impl GidMetaPlugin { - pub fn new() -> GidMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> GidMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + GidMetaPlugin { meta_name: "gid".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> GidMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for GidMetaPlugin { @@ -260,13 +340,33 @@ pub struct GroupMetaPlugin { } impl GroupMetaPlugin { - pub fn new() -> GroupMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> GroupMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + GroupMetaPlugin { meta_name: "group".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> GroupMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for GroupMetaPlugin { @@ -322,13 +422,33 @@ pub struct ShellMetaPlugin { } impl ShellMetaPlugin { - pub fn new() -> ShellMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> ShellMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + ShellMetaPlugin { meta_name: "shell".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> ShellMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for ShellMetaPlugin { @@ -384,13 +504,33 @@ pub struct ShellPidMetaPlugin { } impl ShellPidMetaPlugin { - pub fn new() -> ShellPidMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> ShellPidMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + ShellPidMetaPlugin { meta_name: "shell_pid".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> ShellPidMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for ShellPidMetaPlugin { @@ -446,13 +586,33 @@ pub struct KeepPidMetaPlugin { } impl KeepPidMetaPlugin { - pub fn new() -> KeepPidMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> KeepPidMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + KeepPidMetaPlugin { meta_name: "keep_pid".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> KeepPidMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for KeepPidMetaPlugin { @@ -505,13 +665,33 @@ pub struct HostnameMetaPlugin { } impl HostnameMetaPlugin { - pub fn new() -> HostnameMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> HostnameMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + HostnameMetaPlugin { meta_name: "hostname".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> HostnameMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for HostnameMetaPlugin { @@ -567,13 +747,33 @@ pub struct FullHostnameMetaPlugin { } impl FullHostnameMetaPlugin { - pub fn new() -> FullHostnameMetaPlugin { + pub fn new( + _options: Option>, + outputs: Option>, + ) -> FullHostnameMetaPlugin { + // Start with default outputs + let mut final_outputs = std::collections::HashMap::new(); + let default_outputs = Self::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); + } + } + FullHostnameMetaPlugin { meta_name: "full_hostname".to_string(), is_saved: false, - outputs: std::collections::HashMap::new(), + outputs: final_outputs, } } + + pub fn new_simple() -> FullHostnameMetaPlugin { + Self::new(None, None) + } +} } impl MetaPlugin for FullHostnameMetaPlugin {