diff --git a/Cargo.toml b/Cargo.toml index e4798b3..49a36e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ base64 = "0.22.1" chrono = "0.4.26" clap = { version = "4.3.10", features = ["derive", "env"] } config = "0.14.0" +ctor = "0.2" directories = "6.0.0" dns-lookup = "2.0.2" enum-map = "2.6.1" diff --git a/src/filter_plugin/head.rs b/src/filter_plugin/head.rs index 00c3546..509899e 100644 --- a/src/filter_plugin/head.rs +++ b/src/filter_plugin/head.rs @@ -1,6 +1,7 @@ use super::{FilterPlugin, FilterOption}; use std::io::{Result, Read, Write, BufRead}; use crate::common::PIPESIZE; +use crate::services::filter_service::register_filter_plugin; pub struct HeadBytesFilter { remaining: usize, @@ -96,3 +97,10 @@ impl FilterPlugin for HeadLinesFilter { ] } } + +// Register the plugin at module initialization time +#[ctor::ctor] +fn register_head_filters() { + register_filter_plugin("head_bytes", || Box::new(HeadBytesFilter::new(0))); + register_filter_plugin("head_lines", || Box::new(HeadLinesFilter::new(0))); +} diff --git a/src/services/filter_service.rs b/src/services/filter_service.rs index baf54bc..5212d2e 100644 --- a/src/services/filter_service.rs +++ b/src/services/filter_service.rs @@ -1,6 +1,8 @@ use crate::filter_plugin::{FilterChain, parse_filter_string}; use std::collections::HashMap; use std::io::{Result, Read, Write}; +use once_cell::sync::Lazy; +use std::sync::Mutex; pub struct FilterService; @@ -48,52 +50,16 @@ impl FilterService { } } +/// Global registry for filter plugins +static FILTER_PLUGIN_REGISTRY: Lazy Box>>> = + Lazy::new(|| Mutex::new(HashMap::new())); + +/// Register a filter plugin with the global registry +pub fn register_filter_plugin(name: &str, constructor: fn() -> Box) { + FILTER_PLUGIN_REGISTRY.lock().unwrap().insert(name.to_string(), constructor); +} + /// Get a map of available filter plugins pub fn get_available_filter_plugins() -> HashMap Box> { - let mut plugins = HashMap::new(); - - // Register all available filter plugins using function pointers - plugins.insert("head_bytes".to_string(), create_head_bytes_filter); - plugins.insert("head_lines".to_string(), create_head_lines_filter); - plugins.insert("tail_bytes".to_string(), create_tail_bytes_filter); - plugins.insert("tail_lines".to_string(), create_tail_lines_filter); - plugins.insert("skip_bytes".to_string(), create_skip_bytes_filter); - plugins.insert("skip_lines".to_string(), create_skip_lines_filter); - plugins.insert("grep".to_string(), create_grep_filter); - plugins.insert("strip_ansi".to_string(), create_strip_ansi_filter); - - plugins -} - -// Helper functions to create each filter plugin -fn create_head_bytes_filter() -> Box { - Box::new(crate::filter_plugin::head::HeadBytesFilter::new(0)) -} - -fn create_head_lines_filter() -> Box { - Box::new(crate::filter_plugin::head::HeadLinesFilter::new(0)) -} - -fn create_tail_bytes_filter() -> Box { - Box::new(crate::filter_plugin::tail::TailBytesFilter::new(0)) -} - -fn create_tail_lines_filter() -> Box { - Box::new(crate::filter_plugin::tail::TailLinesFilter::new(0)) -} - -fn create_skip_bytes_filter() -> Box { - Box::new(crate::filter_plugin::skip::SkipBytesFilter::new(0)) -} - -fn create_skip_lines_filter() -> Box { - Box::new(crate::filter_plugin::skip::SkipLinesFilter::new(0)) -} - -fn create_grep_filter() -> Box { - Box::new(crate::filter_plugin::grep::GrepFilter::new("".to_string()).unwrap()) -} - -fn create_strip_ansi_filter() -> Box { - Box::new(crate::filter_plugin::strip_ansi::StripAnsiFilter::new()) + FILTER_PLUGIN_REGISTRY.lock().unwrap().clone() }