From 9f7534f0ae20b53946640ea756ac55649bc22857 Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Wed, 10 Sep 2025 15:40:04 -0300 Subject: [PATCH] docs: Improve Rustdoc for compression engine, delete mode, and parser modules Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) --- PLAN.md | 6 +- src/compression_engine.rs | 151 +++++++++++++++++++++++++++++++------- src/modes/delete.rs | 23 +++++- src/parser/mod.rs | 11 +++ 4 files changed, 162 insertions(+), 29 deletions(-) diff --git a/PLAN.md b/PLAN.md index 67ad9bc..4f250de 100644 --- a/PLAN.md +++ b/PLAN.md @@ -213,15 +213,15 @@ Private helpers (e.g., internal `fn` without `pub`) are not flagged, as they don - `new()` function: Partial. - Impl `FilterPlugin` methods: No docs. -36. **src/compression_engine.rs** +36. **src/compression_engine.rs** [DONE] - `CompressionType` enum: No doc. - `CompressionEngine` trait: Partial. - Functions (`get_compression_engine`, `default_compression_type`): Partial. -37. **src/modes/delete.rs** +37. **src/modes/delete.rs** [DONE] - `mode_delete()` function: Partial. -38. **src/parser/mod.rs** +38. **src/parser/mod.rs** [DONE] - Re-exports: No docs needed. 39. **src/meta_plugin/hostname.rs** diff --git a/src/compression_engine.rs b/src/compression_engine.rs index 142bdc8..74b11e2 100755 --- a/src/compression_engine.rs +++ b/src/compression_engine.rs @@ -22,7 +22,18 @@ use crate::compression_engine::lz4::CompressionEngineLZ4; use crate::compression_engine::none::CompressionEngineNone; use crate::compression_engine::program::CompressionEngineProgram; -/// Enum representing different compression types supported by the system +/// Enum representing different compression types supported by the system. +/// +/// This enum defines all supported compression formats that can be used for +/// storing and retrieving compressed items. Each variant corresponds to a +/// specific compression algorithm or no compression. +/// +/// # Examples +/// +/// ``` +/// use keep::compression_engine::CompressionType; +/// assert_eq!(CompressionType::GZip.to_string(), "gzip"); +/// ``` #[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString, Enum)] #[strum(ascii_case_insensitive)] pub enum CompressionType { @@ -34,49 +45,90 @@ pub enum CompressionType { None, } -/// Trait defining the interface for compression engines +/// Trait defining the interface for compression engines. +/// +/// This trait provides a unified API for different compression implementations. +/// Implementors handle reading from and writing to compressed files, as well as +/// utility operations like copying decompressed content or calculating sizes. +/// +/// # Errors +/// +/// Methods may return `anyhow::Error` for I/O failures, unsupported formats, +/// or invalid file paths. +/// +/// # Examples +/// +/// ``` +/// // Example usage would depend on a concrete implementation +/// use keep::compression_engine::CompressionEngine; +/// let engine = /* some engine */; +/// let reader = engine.open("file.gz".into()).unwrap(); +/// ``` pub trait CompressionEngine { - /// Opens a compressed file for reading + /// Opens a compressed file for reading. + /// + /// Creates a reader that transparently decompresses the file contents as they are read. /// /// # Arguments /// - /// * `file_path` - Path to the compressed file + /// * `file_path` - Path to the compressed file. /// /// # Returns /// - /// * `Result>` - A boxed reader that decompresses the file on read + /// * `Result>` - A boxed reader that decompresses the file on read, + /// or an error if the file cannot be opened or is invalid. + /// + /// # Errors + /// + /// Returns an error if the file does not exist, is not a valid compressed file, + /// or if decompression fails. fn open(&self, file_path: PathBuf) -> Result>; - /// Creates a new compressed file for writing + /// Creates a new compressed file for writing. + /// + /// Creates a writer that transparently compresses data as it is written. /// /// # Arguments /// - /// * `file_path` - Path where the compressed file will be created + /// * `file_path` - Path where the compressed file will be created. /// /// # Returns /// - /// * `Result>` - A boxed writer that compresses data on write + /// * `Result>` - A boxed writer that compresses data on write, + /// or an error if the file cannot be created. + /// + /// # Errors + /// + /// Returns an error if the path is invalid or if there are permission issues. fn create(&self, file_path: PathBuf) -> Result>; - /// Checks if this compression engine is supported on the current system + /// Checks if this compression engine is supported on the current system. + /// + /// Some compression types may require external programs or features to be enabled. /// /// # Returns /// - /// * `bool` - True if supported, false otherwise + /// * `bool` - True if supported, false otherwise. fn is_supported(&self) -> bool { true } - /// Copies decompressed content from a file to a writer + /// Copies decompressed content from a file to a writer. + /// + /// Reads the compressed file and writes the decompressed content to the provided writer. /// /// # Arguments /// - /// * `file_path` - Path to the compressed file - /// * `writer` - Writer to receive decompressed content + /// * `file_path` - Path to the compressed file. + /// * `writer` - Writer to receive decompressed content. /// /// # Returns /// - /// * `Result<()>` - Success or error + /// * `Result<()>` - Success if the copy completes, or an error. + /// + /// # Errors + /// + /// Propagates errors from opening the file or copying data. fn copy(&self, file_path: PathBuf, writer: &mut dyn Write) -> Result<()> { let mut reader = self.open(file_path)?; io::copy(&mut reader, writer)?; @@ -84,29 +136,49 @@ pub trait CompressionEngine { Ok(()) } - /// Decompresses and outputs file content to stdout + /// Decompresses and outputs file content to stdout. + /// + /// Convenience method to decompress and print the contents of a compressed file. /// /// # Arguments /// - /// * `file_path` - Path to the compressed file + /// * `file_path` - Path to the compressed file. /// /// # Returns /// - /// * `Result<()>` - Success or error + /// * `Result<()>` - Success if the content is output, or an error. + /// + /// # Errors + /// + /// Propagates errors from copying to stdout. fn cat(&self, file_path: PathBuf) -> Result<()> { let mut stdout = io::stdout().lock(); self.copy(file_path, &mut stdout) } - /// Calculates the decompressed size of a file + /// Calculates the decompressed size of a file. + /// + /// Reads the entire decompressed content to determine its size in bytes. /// /// # Arguments /// - /// * `file_path` - Path to the compressed file + /// * `file_path` - Path to the compressed file. /// /// # Returns /// - /// * `Result` - The decompressed size in bytes + /// * `Result` - The decompressed size in bytes, or an error. + /// + /// # Errors + /// + /// Returns an error if the file cannot be opened or read. + /// + /// # Examples + /// + /// ``` + /// let engine = /* some engine */; + /// let size = engine.size("file.gz".into()).unwrap(); + /// println!("Decompressed size: {} bytes", size); + /// ``` fn size(&self, file_path: PathBuf) -> Result { let mut reader = self.open(file_path)?; let mut buffer = [0; libc::BUFSIZ as usize]; @@ -159,15 +231,32 @@ lazy_static! { }; } -/// Gets a compression engine for the specified compression type +/// Gets a compression engine for the specified compression type. +/// +/// Dynamically selects and instantiates the appropriate compression engine +/// based on feature flags and available external programs. /// /// # Arguments /// -/// * `compression_type` - The type of compression to use +/// * `compression_type` - The type of compression to use. /// /// # Returns /// -/// * `Result>` - A boxed compression engine instance +/// * `Result>` - A boxed compression engine instance, +/// or an error if the type is not supported. +/// +/// # Errors +/// +/// Returns an error if the specified compression type is not available due to +/// missing features or external programs. +/// +/// # Examples +/// +/// ``` +/// use keep::compression_engine::{get_compression_engine, CompressionType}; +/// let engine = get_compression_engine(CompressionType::GZip).unwrap(); +/// assert!(engine.is_supported()); +/// ``` pub fn get_compression_engine( compression_type: CompressionType, ) -> Result> { @@ -212,11 +301,23 @@ pub fn get_compression_engine( } } -/// Gets the default compression type based on available support +/// Gets the default compression type based on available support. +/// +/// Iterates through all compression types and returns the first one that is +/// supported on the current system. Falls back to `None` if no compression +/// is available. /// /// # Returns /// -/// * `CompressionType` - The first supported compression type found +/// * `CompressionType` - The first supported compression type found. +/// +/// # Examples +/// +/// ``` +/// use keep::compression_engine::default_compression_type; +/// let default = default_compression_type(); +/// println!("Default compression: {}", default); +/// ``` pub fn default_compression_type() -> CompressionType { let mut default = CompressionType::None; for compression_type in CompressionType::iter() { diff --git a/src/modes/delete.rs b/src/modes/delete.rs index 1e07e53..064e010 100644 --- a/src/modes/delete.rs +++ b/src/modes/delete.rs @@ -10,6 +10,11 @@ use rusqlite::Connection; /// Handles the delete mode: removes items by ID from the database and storage. /// +/// This function processes a list of item IDs, attempting to delete each from +/// both the database and the underlying file storage. It skips items that are +/// not found and logs warnings for them. Validation of arguments (e.g., ensuring +/// IDs are provided and tags are empty) is handled at the clap parsing level. +/// /// # Arguments /// /// * `_cmd` - Clap command for error handling (unused). @@ -22,7 +27,23 @@ use rusqlite::Connection; /// /// # Returns /// -/// `Result<()>` on success, or an error if deletion fails. +/// `Result<()>` on success, or an error if deletion fails for any item. +/// +/// # Errors +/// +/// Returns an `anyhow::Error` if a deletion operation fails due to database +/// or I/O issues (excluding `ItemNotFound`, which is handled gracefully). +/// +/// # Examples +/// +/// ``` +/// // This would be called from main after parsing args +/// mode_delete(&mut cmd, &settings, &config, &mut vec![1, 2], &mut vec![], &mut conn, data_path)?; +/// ``` +/// +/// # Panics +/// +/// None. pub fn mode_delete( _cmd: &mut Command, _settings: &config::Settings, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5374f00..aea4897 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,4 +1,15 @@ /// Parsing utilities for filters and other inputs. +/// +/// This module provides tools for parsing filter strings and other structured +/// inputs used throughout the application. Currently, it includes a pest-based +/// parser for filter expressions. +/// +/// # Examples +/// +/// ``` +/// use keep::parser::parse_filter_string; +/// let filters = parse_filter_string("head:5|grep:hello").unwrap(); +/// ``` pub mod filter_parser; pub use filter_parser::{FilterParser, parse_filter_string};