docs: Add comprehensive rustdoc for filter_service.rs
Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
@@ -4,13 +4,63 @@ use std::io::{Result, Read, Write};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// Service for managing filter chains and plugin registration.
|
||||
///
|
||||
/// The `FilterService` provides functionality to parse filter strings, create filter chains,
|
||||
/// and apply them to input/output streams. It integrates with the global filter plugin
|
||||
/// registry to support dynamic loading of filter implementations like `head`, `tail`,
|
||||
/// `grep`, and custom plugins.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// ```rust
|
||||
/// let service = FilterService::new();
|
||||
/// let chain = service.create_filter_chain(Some("head_lines(10)")).unwrap();
|
||||
/// service.filter_data(&mut chain, &mut reader, &mut writer)?;
|
||||
/// ```
|
||||
pub struct FilterService;
|
||||
|
||||
impl FilterService {
|
||||
/// Creates a new `FilterService` instance.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A new `FilterService`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let service = FilterService::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
/// Creates a filter chain from a filter string specification.
|
||||
///
|
||||
/// Parses the filter string using the filter parser and constructs a `FilterChain`
|
||||
/// with the appropriate plugins. Returns `None` if no filter string is provided.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `filter_str` - Optional filter string, e.g., "head_lines(10),grep(pattern=error)".
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<Option<FilterChain>, io::Error>` - The parsed chain or an error if parsing fails.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// * `io::Error` - If the filter string is invalid or parsing fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let chain = service.create_filter_chain(Some("head_lines(10)"))?;
|
||||
/// assert!(chain.is_some());
|
||||
/// let empty = service.create_filter_chain(None)?;
|
||||
/// assert!(empty.is_none());
|
||||
/// ```
|
||||
pub fn create_filter_chain(&self, filter_str: Option<&str>) -> Result<Option<FilterChain>> {
|
||||
if let Some(filter_str) = filter_str {
|
||||
parse_filter_string(filter_str).map(Some)
|
||||
@@ -19,6 +69,32 @@ impl FilterService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a filter chain to input data and writes to output.
|
||||
///
|
||||
/// If a filter chain is provided, it processes the data through each filter in sequence.
|
||||
/// If no chain is provided, it copies the input directly to the output.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// * `R` - Type implementing `Read` for the input source.
|
||||
/// * `W` - Type implementing `Write` for the output destination.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `chain` - Mutable reference to an optional filter chain.
|
||||
/// * `reader` - Mutable reference to the input reader.
|
||||
/// * `writer` - Mutable reference to the output writer.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<(), io::Error>` - Success or I/O error if filtering fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let mut chain = parse_filter_string("head_lines(5)")?;
|
||||
/// service.filter_data(&mut chain, &mut reader, &mut writer)?;
|
||||
/// ```
|
||||
pub fn filter_data<R: Read, W: Write>(
|
||||
&self,
|
||||
chain: &mut Option<FilterChain>,
|
||||
@@ -34,7 +110,26 @@ impl FilterService {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to process data with a filter string in one call
|
||||
/// Processes data with an optional filter string in a single call.
|
||||
///
|
||||
/// This is a convenience method that creates a filter chain, applies it to the data,
|
||||
/// and returns the filtered result as a byte vector. Useful for simple one-off filtering.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `data` - Input byte slice to process.
|
||||
/// * `filter_str` - Optional filter string to apply.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * `Result<Vec<u8>, io::Error>` - Filtered data or error if filtering fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let filtered = service.process_with_filter(b"Hello\nWorld\n", Some("head_lines(1)"))?;
|
||||
/// assert_eq!(filtered, b"Hello\n");
|
||||
/// ```
|
||||
pub fn process_with_filter(&self, data: &[u8], filter_str: Option<&str>) -> Result<Vec<u8>> {
|
||||
let mut chain = self.create_filter_chain(filter_str)?;
|
||||
let mut reader = std::io::Cursor::new(data);
|
||||
@@ -50,16 +145,65 @@ impl FilterService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Global registry for filter plugins
|
||||
/// Global registry for filter plugins.
|
||||
///
|
||||
/// This static variable holds a thread-safe map of filter plugin names to their
|
||||
/// constructors. Plugins register themselves at initialization time using
|
||||
/// `register_filter_plugin`. The registry is lazily initialized on first access.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// Plugins use this registry for dynamic loading:
|
||||
///
|
||||
/// ```rust
|
||||
/// static FILTER_PLUGIN_REGISTRY: Lazy<Mutex<HashMap<String, fn() -> Box<dyn FilterPlugin>>>> =
|
||||
/// Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
/// ```
|
||||
static FILTER_PLUGIN_REGISTRY: Lazy<Mutex<HashMap<String, fn() -> Box<dyn crate::filter_plugin::FilterPlugin>>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
/// Register a filter plugin with the global registry
|
||||
/// Register a filter plugin with the global registry.
|
||||
///
|
||||
/// Adds a filter plugin to the registry so it can be dynamically loaded by name.
|
||||
/// This function is typically called at module initialization time using `#[ctor::ctor]`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - The name of the filter plugin (e.g., "head_lines").
|
||||
/// * `constructor` - A function that returns a new `Box<dyn FilterPlugin>` instance.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the registry lock cannot be acquired (unlikely in normal use).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// register_filter_plugin("my_filter", || Box::new(MyFilter::new()));
|
||||
/// ```
|
||||
pub fn register_filter_plugin(name: &str, constructor: fn() -> Box<dyn crate::filter_plugin::FilterPlugin>) {
|
||||
FILTER_PLUGIN_REGISTRY.lock().unwrap().insert(name.to_string(), constructor);
|
||||
}
|
||||
|
||||
/// Get a map of available filter plugins
|
||||
/// Get a map of available filter plugins.
|
||||
///
|
||||
/// Returns a copy of the current registry contents, mapping plugin names to their constructors.
|
||||
/// This is useful for status reporting or plugin discovery.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// `HashMap<String, fn() -> Box<dyn FilterPlugin>>` - A clone of the registry map.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the registry lock cannot be acquired.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// let available = get_available_filter_plugins();
|
||||
/// assert!(available.contains_key("head_lines"));
|
||||
/// ```
|
||||
pub fn get_available_filter_plugins() -> HashMap<String, fn() -> Box<dyn crate::filter_plugin::FilterPlugin>> {
|
||||
FILTER_PLUGIN_REGISTRY.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user