diff --git a/src/compression_engine/gzip.rs b/src/compression_engine/gzip.rs index d4ff16b..aeb60db 100644 --- a/src/compression_engine/gzip.rs +++ b/src/compression_engine/gzip.rs @@ -1,8 +1,18 @@ +```rust /// GZip compression engine module. /// /// This module provides the implementation for GZip compression and decompression /// using the `flate2` crate. It includes the main `CompressionEngineGZip` struct /// and supporting types for handling GZip streams. +/// +/// # Usage +/// +/// ```rust +/// use keep::compression_engine::get_compression_engine; +/// let engine = get_compression_engine(keep::compression_engine::CompressionType::GZip) +/// .expect("GZip engine creation failed"); +/// let reader = engine.open("/path/to/file.gz".into()).expect("Open failed"); +/// ``` use anyhow::Result; use log::*; use std::fs::File; @@ -16,11 +26,20 @@ use flate2::write::GzEncoder; use crate::compression_engine::CompressionEngine; +```rust /// GZip compression engine implementation. /// /// This struct provides the functionality to compress and decompress data using /// the GZip algorithm. It implements the `CompressionEngine` trait for integration /// with the compression service. +/// +/// # Examples +/// +/// ```rust +/// let engine = keep::compression_engine::get_compression_engine(keep::compression_engine::CompressionType::GZip) +/// .expect("Failed to get GZip engine"); +/// assert!(engine.is_supported()); +/// ``` #[derive(Debug, Eq, PartialEq, Clone, Default)] pub struct CompressionEngineGZip {} @@ -30,6 +49,12 @@ impl CompressionEngineGZip { /// # Returns /// /// A new `CompressionEngineGZip` instance. + /// + /// # Examples + /// + /// ``` + /// let engine = CompressionEngineGZip::new(); + /// ``` pub fn new() -> CompressionEngineGZip { CompressionEngineGZip {} } @@ -44,6 +69,13 @@ impl CompressionEngine for CompressionEngineGZip { /// # Returns /// /// Always returns `true` since GZip is built-in. + /// + /// # Examples + /// + /// ``` + /// let engine = CompressionEngineGZip::new(); + /// assert!(engine.is_supported()); + /// ``` fn is_supported(&self) -> bool { true } @@ -60,6 +92,16 @@ impl CompressionEngine for CompressionEngineGZip { /// # Returns /// /// * `Result>` - A boxed reader that decompresses the GZip file on read. + /// + /// # Errors + /// + /// * `anyhow::Error` - If the file cannot be opened or decoded. + /// + /// # Examples + /// + /// ``` + /// let reader = engine.open("/path/to/file.gz".into()).expect("Open failed"); + /// ``` fn open(&self, file_path: PathBuf) -> Result> { debug!("COMPRESSION: Opening {:?} using {:?}", file_path, *self); @@ -80,6 +122,16 @@ impl CompressionEngine for CompressionEngineGZip { /// # Returns /// /// * `Result>` - A boxed writer that compresses data using GZip on write. + /// + /// # Errors + /// + /// * `anyhow::Error` - If the file cannot be created or encoder fails. + /// + /// # Examples + /// + /// ``` + /// let writer = engine.create("/path/to/file.gz".into()).expect("Create failed"); + /// ``` fn create(&self, file_path: PathBuf) -> Result> { debug!("COMPRESSION: Writting to {:?} using {:?}", file_path, *self); @@ -90,10 +142,20 @@ impl CompressionEngine for CompressionEngineGZip { } } +```rust /// Auto-finishing GZip encoder that automatically calls finish on drop. /// /// This wrapper ensures that the GZip stream is properly closed even if the /// writer is dropped unexpectedly, preventing incomplete compression files. +/// +/// # Examples +/// +/// ```rust +/// let file = File::create("test.gz").unwrap(); +/// let encoder = GzEncoder::new(file, Compression::default()); +/// let auto_encoder = AutoFinishGzEncoder::new(encoder); +/// // Encoder will finish on drop +/// ``` pub struct AutoFinishGzEncoder { encoder: Option>, } @@ -108,6 +170,14 @@ impl AutoFinishGzEncoder { /// # Returns /// /// A new `AutoFinishGzEncoder` instance. + /// + /// # Examples + /// + /// ``` + /// let file = File::create("test.gz").unwrap(); + /// let encoder = GzEncoder::new(file, Compression::default()); + /// let auto_encoder = AutoFinishGzEncoder::new(encoder); + /// ``` fn new(gz_encoder: GzEncoder) -> AutoFinishGzEncoder { AutoFinishGzEncoder { encoder: Some(gz_encoder), @@ -120,6 +190,10 @@ impl Drop for AutoFinishGzEncoder { /// /// This method ensures the GZip stream is properly closed by calling `finish()` /// on the underlying encoder. + /// + /// # Errors + /// + /// Errors during finish are logged but ignored. fn drop(&mut self) { if let Some(encoder) = self.encoder.take() { debug!("COMPRESSION: Finishing"); @@ -138,6 +212,10 @@ impl Write for AutoFinishGzEncoder { /// # Returns /// /// * `io::Result` - The number of bytes written or an I/O error. + /// + /// # Errors + /// + /// Propagates errors from the underlying encoder. fn write(&mut self, buf: &[u8]) -> io::Result { self.encoder.as_mut().unwrap().write(buf) } @@ -147,6 +225,10 @@ impl Write for AutoFinishGzEncoder { /// # Returns /// /// * `io::Result<()>` - Success or an I/O error. + /// + /// # Errors + /// + /// Propagates errors from the underlying encoder. fn flush(&mut self) -> io::Result<()> { self.encoder.as_mut().unwrap().flush() } diff --git a/src/modes/server/common.rs b/src/modes/server/common.rs index 7c46b7d..ac89b81 100644 --- a/src/modes/server/common.rs +++ b/src/modes/server/common.rs @@ -3,6 +3,14 @@ /// This module provides shared structures, functions, and middleware used across /// different parts of the server implementation, including configuration, state /// management, API responses, authentication, and logging. +/// +/// # Usage +/// +/// ```rust +/// use keep::modes::server::common::{ServerConfig, AppState}; +/// let config = ServerConfig { address: "127.0.0.1".to_string(), ..Default::default() }; +/// let state = AppState { /* ... */ }; +/// ``` use anyhow::Result; use axum::{ extract::{Request, ConnectInfo}, @@ -26,6 +34,17 @@ use crate::services::item_service::ItemService; /// /// This struct holds the configuration parameters for the HTTP server, including /// binding address, port, and authentication settings. +/// +/// # Examples +/// +/// ``` +/// let config = ServerConfig { +/// address: "127.0.0.1".to_string(), +/// port: Some(8080), +/// password: None, +/// password_hash: None, +/// }; +/// ``` #[derive(Debug, Clone)] pub struct ServerConfig { /// Server bind address. @@ -50,11 +69,6 @@ pub struct ServerConfig { pub password_hash: Option, } -/// Application state shared across all routes. -/// -/// This struct encapsulates the shared state that is accessible to all request handlers, -/// including database connections, file paths, services, and configuration. -#[derive(Clone)] /// Application state shared across all routes. /// /// This struct encapsulates the shared state that is accessible to all request handlers, @@ -62,7 +76,10 @@ pub struct ServerConfig { /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::AppState; +/// use std::sync::Arc; +/// use tokio::sync::Mutex; /// let state = AppState { /// db: Arc::new(Mutex::new(conn)), /// data_dir: PathBuf::from("/data"), @@ -71,6 +88,7 @@ pub struct ServerConfig { /// settings: Arc::new(settings), /// }; /// ``` +#[derive(Clone)] pub struct AppState { /// Database connection wrapped in Arc. /// @@ -95,11 +113,6 @@ pub struct AppState { pub settings: Arc, } -/// Standard API response wrapper containing success status, data payload, and error information. -/// -/// This generic type is used for all API responses to provide a consistent structure across -/// different endpoints. -#[derive(Debug, Serialize, Deserialize, ToSchema)] /// Standard API response wrapper containing success status, data payload, and error information. /// /// This generic type is used for all API responses to provide a consistent structure across @@ -111,13 +124,15 @@ pub struct AppState { /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ApiResponse; /// let response: ApiResponse> = ApiResponse { /// success: true, /// data: Some(items), /// error: None, /// }; /// ``` +#[derive(Debug, Serialize, Deserialize, ToSchema)] #[schema(description = "Standard API response wrapper containing success status, data payload, and error information")] pub struct ApiResponse { /// Success indicator. @@ -134,23 +149,21 @@ pub struct ApiResponse { pub error: Option, } -/// Response type for list of item information. -/// -/// Specialized response for endpoints that return multiple items. -#[derive(Serialize, Deserialize, ToSchema)] /// Response type for list of item information. /// /// Specialized response for endpoints that return multiple items. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemInfoListResponse; /// let response = ItemInfoListResponse { /// success: true, /// data: Some(vec![item_info]), /// error: None, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] pub struct ItemInfoListResponse { /// Success indicator. /// @@ -166,23 +179,21 @@ pub struct ItemInfoListResponse { pub error: Option, } -/// Response type for single item information. -/// -/// Specialized response for endpoints that return a single item's details. -#[derive(Serialize, Deserialize, ToSchema)] /// Response type for single item information. /// /// Specialized response for endpoints that return a single item's details. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemInfoResponse; /// let response = ItemInfoResponse { /// success: true, /// data: Some(item_info), /// error: None, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] pub struct ItemInfoResponse { /// Success indicator. /// @@ -198,23 +209,21 @@ pub struct ItemInfoResponse { pub error: Option, } -/// Response type for item content information. -/// -/// Specialized response for endpoints that return item content and related metadata. -#[derive(Serialize, Deserialize, ToSchema)] /// Response type for item content information. /// /// Specialized response for endpoints that return item content and related metadata. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemContentInfoResponse; /// let response = ItemContentInfoResponse { /// success: true, /// data: Some(content_info), /// error: None, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] pub struct ItemContentInfoResponse { /// Success indicator. /// @@ -230,23 +239,21 @@ pub struct ItemContentInfoResponse { pub error: Option, } -/// Response type for metadata. -/// -/// Specialized response for metadata-only endpoints. -#[derive(Serialize, Deserialize, ToSchema)] /// Response type for metadata. /// /// Specialized response for metadata-only endpoints. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::MetadataResponse; /// let response = MetadataResponse { /// success: true, /// data: Some(meta_map), /// error: None, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] pub struct MetadataResponse { /// Success indicator. /// @@ -262,23 +269,21 @@ pub struct MetadataResponse { pub error: Option, } -/// Response type for status information. -/// -/// Specialized response for system status endpoints. -#[derive(Serialize, Deserialize, ToSchema)] /// Response type for status information. /// /// Specialized response for system status endpoints. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::StatusInfoResponse; /// let response = StatusInfoResponse { /// success: true, /// data: Some(status_info), /// error: None, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] pub struct StatusInfoResponse { /// Success indicator. /// @@ -294,11 +299,6 @@ pub struct StatusInfoResponse { pub error: Option, } -/// Complete information about a stored item including metadata and tags. -/// -/// This structure represents the full details of an item, combining basic item -/// properties with associated tags and metadata. -#[derive(Serialize, Deserialize, ToSchema)] /// Complete information about a stored item including metadata and tags. /// /// This structure represents the full details of an item, combining basic item @@ -306,7 +306,9 @@ pub struct StatusInfoResponse { /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemInfo; +/// use std::collections::HashMap; /// let item_info = ItemInfo { /// id: 42, /// ts: "2023-12-01T15:30:45Z".to_string(), @@ -316,6 +318,7 @@ pub struct StatusInfoResponse { /// metadata: HashMap::from([("mime_type".to_string(), "text/plain".to_string())]), /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] #[schema(description = "Complete information about a stored item including metadata and tags")] pub struct ItemInfo { /// Item ID. @@ -350,17 +353,6 @@ pub struct ItemInfo { pub metadata: HashMap, } -/// Item information including content and metadata, with binary detection. -/// -/// This structure provides item details along with its content, handling binary -/// content detection and safe string representation. -/// -/// # Fields -/// -/// * `metadata` - Flattened metadata HashMap. -/// * `content` - Optional string content (text only). -/// * `binary` - True if binary content. -#[derive(Serialize, Deserialize, ToSchema)] /// Item information including content and metadata, with binary detection. /// /// This structure provides item details along with its content, handling binary @@ -368,13 +360,16 @@ pub struct ItemInfo { /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemContentInfo; +/// use std::collections::HashMap; /// let content_info = ItemContentInfo { /// metadata: HashMap::from([("mime_type".to_string(), "text/plain".to_string())]), /// content: Some("Hello, world!".to_string()), /// binary: false, /// }; /// ``` +#[derive(Serialize, Deserialize, ToSchema)] #[schema(description = "Item information including content and metadata, with binary detection")] pub struct ItemContentInfo { /// Metadata hashmap. @@ -395,23 +390,17 @@ pub struct ItemContentInfo { pub binary: bool, } -/// Query parameters for tags. -/// -/// Structure for handling tag-based query parameters in API requests. -/// -/// # Fields -/// -/// * `tags` - Optional comma-separated tags for filtering. -#[derive(Debug, Deserialize)] /// Query parameters for tags. /// /// Structure for handling tag-based query parameters in API requests. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::TagsQuery; /// let query = TagsQuery { tags: Some("tag1,tag2".to_string()) }; /// ``` +#[derive(Debug, Deserialize)] pub struct TagsQuery { /// Optional comma-separated tags. /// @@ -419,24 +408,14 @@ pub struct TagsQuery { pub tags: Option, } -/// Query parameters for listing items. -/// -/// Structure for pagination and sorting parameters in item listing endpoints. -/// -/// # Fields -/// -/// * `tags` - Optional tags for filtering. -/// * `order` - Optional sort: "newest" or "oldest". -/// * `start` - Optional start index. -/// * `count` - Optional item limit. -#[derive(Debug, Deserialize)] /// Query parameters for listing items. /// /// Structure for pagination and sorting parameters in item listing endpoints. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ListItemsQuery; /// let query = ListItemsQuery { /// tags: Some("important".to_string()), /// order: Some("newest".to_string()), @@ -444,6 +423,7 @@ pub struct TagsQuery { /// count: Some(10), /// }; /// ``` +#[derive(Debug, Deserialize)] pub struct ListItemsQuery { /// Optional comma-separated tags for filtering. /// @@ -463,25 +443,14 @@ pub struct ListItemsQuery { pub count: Option, } -/// Query parameters for item retrieval. -/// -/// Structure for content retrieval parameters, including binary handling and streaming options. -/// -/// # Fields -/// -/// * `allow_binary` - Allow binary (default true). -/// * `offset` - Byte offset (default 0). -/// * `length` - Byte length (default 0 = all). -/// * `stream` - Enable streaming (default false). -/// * `as_meta` - Return as JSON metadata (default false). -#[derive(Debug, Deserialize, utoipa::ToSchema)] /// Query parameters for item retrieval. /// /// Structure for content retrieval parameters, including binary handling and streaming options. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemQuery; /// let query = ItemQuery { /// allow_binary: true, /// offset: 0, @@ -490,6 +459,7 @@ pub struct ListItemsQuery { /// as_meta: false, /// }; /// ``` +#[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct ItemQuery { /// Allow binary content (default: true). /// @@ -518,26 +488,14 @@ pub struct ItemQuery { pub as_meta: bool, } -/// Query parameters for item content retrieval. -/// -/// Extended query parameters for content-specific operations, including tag filtering. -/// -/// # Fields -/// -/// * `tags` - Optional tags for filtering. -/// * `allow_binary` - Allow binary (default true). -/// * `offset` - Byte offset (default 0). -/// * `length` - Byte length (default 0 = all). -/// * `stream` - Enable streaming (default false). -/// * `as_meta` - Return as JSON metadata (default false). -#[derive(Debug, Deserialize, utoipa::ToSchema)] /// Query parameters for item content retrieval. /// /// Extended query parameters for content-specific operations, including tag filtering. /// /// # Examples /// -/// ``` +/// ```rust +/// use keep::modes::server::common::ItemContentQuery; /// let query = ItemContentQuery { /// tags: Some("important".to_string()), /// allow_binary: true, @@ -547,6 +505,7 @@ pub struct ItemQuery { /// as_meta: false, /// }; /// ``` +#[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct ItemContentQuery { /// Optional comma-separated tags for filtering. ///