From c965e9f51cd4138a46f08ade398fb78af4c04f46 Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Wed, 10 Sep 2025 12:10:36 -0300 Subject: [PATCH] docs: Add rustdoc to all files, document arguments and returns Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) --- src/compression_engine/gzip.rs | 27 ++- src/modes/diff.rs | 75 ++++--- src/modes/list.rs | 100 ++++++++- src/modes/server/common.rs | 361 ++++++++++++++++++++++++--------- 4 files changed, 442 insertions(+), 121 deletions(-) diff --git a/src/compression_engine/gzip.rs b/src/compression_engine/gzip.rs index 9e9a2f8..d4ff16b 100644 --- a/src/compression_engine/gzip.rs +++ b/src/compression_engine/gzip.rs @@ -1,3 +1,8 @@ +/// 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. use anyhow::Result; use log::*; use std::fs::File; @@ -11,7 +16,11 @@ use flate2::write::GzEncoder; use crate::compression_engine::CompressionEngine; -/// GZip compression engine implementation +/// 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. #[derive(Debug, Eq, PartialEq, Clone, Default)] pub struct CompressionEngineGZip {} @@ -29,6 +38,9 @@ impl CompressionEngineGZip { impl CompressionEngine for CompressionEngineGZip { /// Checks if GZip compression is supported. /// + /// GZip is a built-in compression method using the `flate2` crate, so it is + /// always supported. + /// /// # Returns /// /// Always returns `true` since GZip is built-in. @@ -38,6 +50,9 @@ impl CompressionEngine for CompressionEngineGZip { /// Opens a GZip compressed file for reading. /// + /// This method creates a `GzDecoder` wrapped around the file, allowing the + /// file to be read as if it were uncompressed. + /// /// # Arguments /// /// * `file_path` - Path to the GZip compressed file. @@ -54,6 +69,10 @@ impl CompressionEngine for CompressionEngineGZip { /// Creates a new GZip compressed file for writing. /// + /// This method creates a file and wraps it in a `GzEncoder` with default + /// compression settings. It uses `AutoFinishGzEncoder` to ensure the GZip + /// stream is properly closed on drop. + /// /// # Arguments /// /// * `file_path` - Path where the GZip compressed file will be created. @@ -73,7 +92,8 @@ impl CompressionEngine for CompressionEngineGZip { /// Auto-finishing GZip encoder that automatically calls finish on drop. /// -/// This ensures the GZip stream is properly closed even if the writer is dropped unexpectedly. +/// This wrapper ensures that the GZip stream is properly closed even if the +/// writer is dropped unexpectedly, preventing incomplete compression files. pub struct AutoFinishGzEncoder { encoder: Option>, } @@ -97,6 +117,9 @@ impl AutoFinishGzEncoder { impl Drop for AutoFinishGzEncoder { /// Automatically finishes the GZip encoding when the writer is dropped. + /// + /// This method ensures the GZip stream is properly closed by calling `finish()` + /// on the underlying encoder. fn drop(&mut self) { if let Some(encoder) = self.encoder.take() { debug!("COMPRESSION: Finishing"); diff --git a/src/modes/diff.rs b/src/modes/diff.rs index cbc3aa9..6cf2778 100644 --- a/src/modes/diff.rs +++ b/src/modes/diff.rs @@ -1,3 +1,7 @@ +/// Diff mode implementation. +/// +/// This module provides functionality for comparing two items and displaying their +/// differences using external diff tools. use anyhow::{Context, Result}; use clap::Command; use std::io::Read; @@ -6,23 +10,16 @@ use crate::config; use crate::services::item_service::ItemService; use log::debug; -fn validate_diff_args(cmd: &mut Command, ids: &Vec, tags: &Vec) -> anyhow::Result<()> { - if !tags.is_empty() { - return Err(anyhow::anyhow!("Tags are not supported with --diff. Please provide exactly two IDs.")); - } - if ids.len() != 2 { - return Err(anyhow::anyhow!("You must supply exactly two IDs when using --diff.")); - } - Ok(()) -} - -/// Validates the diff arguments and exits with error if invalid +/// Validates diff arguments and exits with error if invalid. +/// +/// This function checks that exactly two item IDs are provided and no tags are used +/// with the diff mode, exiting with an appropriate error message if validation fails. /// /// # Arguments /// -/// * `cmd` - Command instance for error reporting -/// * `ids` - Vector of item IDs -/// * `tags` - Vector of tags (should be empty for diff mode) +/// * `cmd` - Command instance for error reporting. +/// * `ids` - Vector of item IDs. +/// * `tags` - Vector of tags (should be empty for diff mode). fn validate_diff_args(cmd: &mut Command, ids: &Vec, tags: &Vec) { if !tags.is_empty() { cmd.error( @@ -40,17 +37,44 @@ fn validate_diff_args(cmd: &mut Command, ids: &Vec, tags: &Vec) { } } -/// Fetches and validates items from the database for diff operation +/// Validates the diff arguments and returns a Result if valid. +/// +/// This function performs the same validation as `validate_diff_args` but returns +/// an error instead of exiting, allowing for programmatic handling. /// /// # Arguments /// -/// * `conn` - Mutable reference to the database connection -/// * `ids` - Vector of item IDs to fetch -/// * `item_service` - Reference to the item service for validation +/// * `cmd` - Command instance for error reporting. +/// * `ids` - Vector of item IDs to fetch. +/// * `tags` - Vector of tags (should be empty for diff mode). /// /// # Returns /// -/// * `Result<(ItemWithMeta, ItemWithMeta)>` - Tuple of items with metadata or error +/// * `anyhow::Result<()>` - Ok if valid, Err with error message if invalid. +fn validate_diff_args(cmd: &mut Command, ids: &Vec, tags: &Vec) -> anyhow::Result<()> { + if !tags.is_empty() { + return Err(anyhow::anyhow!("Tags are not supported with --diff. Please provide exactly two IDs.")); + } + if ids.len() != 2 { + return Err(anyhow::anyhow!("You must supply exactly two IDs when using --diff.")); + } + Ok(()) +} + +/// Fetches and validates items from the database for diff operation. +/// +/// This function retrieves two items by their IDs from the database using the +/// item service, which handles validation, and returns them as a tuple. +/// +/// # Arguments +/// +/// * `conn` - Mutable reference to the database connection. +/// * `ids` - Vector of item IDs to fetch. +/// * `item_service` - Reference to the item service for validation. +/// +/// # Returns +/// +/// * `Result<(ItemWithMeta, ItemWithMeta)>` - Tuple of items with metadata or error. fn fetch_and_validate_items( conn: &mut rusqlite::Connection, ids: &Vec, @@ -70,17 +94,20 @@ fn fetch_and_validate_items( Ok((item_a, item_b)) } -/// Sets up file paths and compression for diff operation +/// Sets up file paths and compression for diff operation. +/// +/// This function constructs the file paths for the two items and prepares the +/// compression engines needed for reading their contents. /// /// # Arguments /// -/// * `item_service` - Reference to the item service -/// * `item_a` - First item with metadata -/// * `item_b` - Second item with metadata +/// * `item_service` - Reference to the item service. +/// * `item_a` - First item with metadata. +/// * `item_b` - Second item with metadata. /// /// # Returns /// -/// * `Result<(PathBuf, PathBuf)>` - Tuple of item file paths or error +/// * `Result<(PathBuf, PathBuf)>` - Tuple of item file paths or error. fn setup_diff_paths_and_compression( item_service: &ItemService, item_a: &crate::services::types::ItemWithMeta, diff --git a/src/modes/list.rs b/src/modes/list.rs index 9abd071..0f6081a 100644 --- a/src/modes/list.rs +++ b/src/modes/list.rs @@ -1,3 +1,8 @@ +/// List mode implementation. +/// +/// This module provides the functionality to list stored items with customizable +/// formatting, filtering by tags, and support for different output formats +/// including table, JSON, and YAML. use crate::config; use crate::services::item_service::ItemService; use crate::services::types::ItemWithMeta; @@ -10,21 +15,68 @@ use serde::{Deserialize, Serialize}; use serde_json; use serde_yaml; +/// Structure representing a list item for structured output formats. +/// +/// This struct holds all the information needed to serialize an item for JSON or +/// YAML output in list mode. #[derive(Serialize, Deserialize)] struct ListItem { + /// Item ID. + /// + /// The unique identifier for the item. id: Option, + /// Timestamp. + /// + /// The formatted timestamp string for the item. time: String, + /// Size in bytes. + /// + /// The raw size of the item content. size: Option, + /// Formatted size. + /// + /// Human-readable size string. size_formatted: String, + /// Compression type. + /// + /// The compression algorithm used for the item. compression: String, + /// File size in bytes. + /// + /// The size of the stored file on disk. file_size: Option, + /// Formatted file size. + /// + /// Human-readable file size string. file_size_formatted: String, + /// File path. + /// + /// The full path to the item's storage file. file_path: String, + /// Tags. + /// + /// Vector of tag names associated with the item. tags: Vec, + /// Metadata. + /// + /// HashMap of metadata key-value pairs. meta: std::collections::HashMap, } -// Helper function to apply color to a cell +// Helper function to apply color to a cell. +/// +/// This function converts the configuration color to a comfy-table Color and +/// applies it to the cell as foreground or background color. +/// +/// # Arguments +/// +/// * `cell` - The cell to modify. +/// * `color` - The color from configuration to apply. +/// * `is_foreground` - True for foreground color, false for background. +/// +/// # Returns +/// +/// The modified cell with color applied. fn apply_color(mut cell: Cell, color: &crate::config::TableColor, is_foreground: bool) -> Cell { use crate::config::TableColor::*; use comfy_table::Color; @@ -57,7 +109,19 @@ fn apply_color(mut cell: Cell, color: &crate::config::TableColor, is_foreground: cell } -// Helper function to apply attribute to a cell +// Helper function to apply attribute to a cell. +/// +/// This function applies a single table attribute to the cell based on the +/// configuration attribute type. +/// +/// # Arguments +/// +/// * `cell` - The cell to modify. +/// * `attribute` - The attribute from configuration to apply. +/// +/// # Returns +/// +/// The modified cell with attribute applied. fn apply_attribute(mut cell: Cell, attribute: &crate::config::TableAttribute) -> Cell { use crate::config::TableAttribute::*; use comfy_table::Attribute; @@ -77,6 +141,23 @@ fn apply_attribute(mut cell: Cell, attribute: &crate::config::TableAttribute) -> cell } +/// Main list mode function. +/// +/// This function handles the listing of items based on tags, applying formatting +/// and output options from settings. It supports table, JSON, and YAML output formats. +/// +/// # Arguments +/// +/// * `cmd` - Mutable reference to the Clap command for error handling. +/// * `settings` - Reference to application settings. +/// * `ids` - Mutable vector of item IDs (should be empty for list mode). +/// * `tags` - Reference to vector of tags for filtering. +/// * `conn` - Mutable reference to database connection. +/// * `data_path` - Path to the data directory. +/// +/// # Returns +/// +/// * `Result<()>` - Success or error if listing fails. pub fn mode_list( cmd: &mut clap::Command, settings: &config::Settings, @@ -235,6 +316,21 @@ pub fn mode_list( Ok(()) } +/// Shows the list of items in a structured format (JSON or YAML). +/// +/// This function converts the list of items to the specified structured format +/// and prints it to stdout. +/// +/// # Arguments +/// +/// * `items_with_meta` - Vector of items with metadata to display. +/// * `data_path` - Path to the data directory for file size calculations. +/// * `settings` - Reference to application settings. +/// * `output_format` - The desired output format (JSON or YAML). +/// +/// # Returns +/// +/// * `Result<()>` - Success or error if serialization fails. fn show_list_structured( items_with_meta: Vec, data_path: std::path::PathBuf, diff --git a/src/modes/server/common.rs b/src/modes/server/common.rs index 69a1254..f1b3599 100644 --- a/src/modes/server/common.rs +++ b/src/modes/server/common.rs @@ -1,3 +1,8 @@ +/// Common utilities and types for the server module. +/// +/// 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. use anyhow::Result; use axum::{ extract::{Request, ConnectInfo}, @@ -17,229 +22,386 @@ use tokio::sync::Mutex; use utoipa::ToSchema; use crate::services::item_service::ItemService; -/// Server configuration structure +/// Server configuration structure. +/// +/// This struct holds the configuration parameters for the HTTP server, including +/// binding address, port, and authentication settings. #[derive(Debug, Clone)] pub struct ServerConfig { - /// Server bind address + /// Server bind address. + /// + /// The IP address or hostname the server should bind to. Defaults to "127.0.0.1" + /// for local-only access. pub address: String, - /// Optional server port + /// Optional server port. + /// + /// The TCP port number to listen on. If not specified, a default port (typically + /// 8080 or 21080) will be used. pub port: Option, - /// Optional authentication password + /// Optional authentication password. + /// + /// Plain text password for basic or bearer token authentication. This should be + /// used only for testing or low-security environments. pub password: Option, - /// Optional hashed authentication password + /// Optional hashed authentication password. + /// + /// Pre-hashed password (Unix crypt format) for secure authentication. Preferred + /// over plain text password for production use. pub password_hash: Option, } -/// Application state shared across all routes +/// 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)] pub struct AppState { - /// Database connection wrapped in Arc + /// Database connection wrapped in Arc. + /// + /// A thread-safe reference to the SQLite database connection, protected by a mutex + /// for concurrent access safety. pub db: Arc>, - /// Data directory path + /// Data directory path. + /// + /// The root directory where item files are stored. pub data_dir: PathBuf, - /// Item service instance + /// Item service instance. + /// + /// Shared reference to the service handling item storage and retrieval operations. pub item_service: Arc, - /// Command line argument parser + /// Command line argument parser. + /// + /// Thread-safe reference to the Clap command builder for configuration access. pub cmd: Arc>, - /// Application settings + /// Application settings. + /// + /// Shared reference to the application's configuration settings. pub settings: Arc, } -/// Standard API response wrapper containing success status, data payload, and error information +/// 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)] #[schema(description = "Standard API response wrapper containing success status, data payload, and error information")] pub struct ApiResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional data payload + /// Optional data payload. + /// + /// The actual response data, present only if the request was successful. pub data: Option, - /// Optional error message + /// Optional error message. + /// + /// Error description, present only if the request failed. pub error: Option, } -/// Response type for list of item information +/// Response type for list of item information. +/// +/// Specialized response for endpoints that return multiple items. #[derive(Serialize, Deserialize, ToSchema)] pub struct ItemInfoListResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional list of item information + /// Optional list of item information. + /// + /// Vector of `ItemInfo` structures containing details about each item. pub data: Option>, - /// Optional error message + /// Optional error message. + /// + /// Error description if the request failed. pub error: Option, } -/// Response type for single item information +/// Response type for single item information. +/// +/// Specialized response for endpoints that return a single item's details. #[derive(Serialize, Deserialize, ToSchema)] pub struct ItemInfoResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional item information + /// Optional item information. + /// + /// The `ItemInfo` structure containing details about the item. pub data: Option, - /// Optional error message + /// Optional error message. + /// + /// Error description if the request failed. pub error: Option, } -/// Response type for item content information +/// Response type for item content information. +/// +/// Specialized response for endpoints that return item content and related metadata. #[derive(Serialize, Deserialize, ToSchema)] pub struct ItemContentInfoResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional item content information + /// Optional item content information. + /// + /// The `ItemContentInfo` structure containing content and metadata. pub data: Option, - /// Optional error message + /// Optional error message. + /// + /// Error description if the request failed. pub error: Option, } -/// Response type for metadata +/// Response type for metadata. +/// +/// Specialized response for metadata-only endpoints. #[derive(Serialize, Deserialize, ToSchema)] pub struct MetadataResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional metadata hashmap + /// Optional metadata hashmap. + /// + /// HashMap containing key-value pairs of metadata. pub data: Option>, - /// Optional error message + /// Optional error message. + /// + /// Error description if the request failed. pub error: Option, } -/// Response type for status information +/// Response type for status information. +/// +/// Specialized response for system status endpoints. #[derive(Serialize, Deserialize, ToSchema)] pub struct StatusInfoResponse { - /// Success indicator + /// Success indicator. + /// + /// Boolean flag indicating whether the request was successful. pub success: bool, - /// Optional status information + /// Optional status information. + /// + /// The `StatusInfo` structure containing system status details. pub data: Option, - /// Optional error message + /// Optional error message. + /// + /// Error description if the request failed. pub error: Option, } -/// Complete information about a stored item including metadata and tags +/// 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)] #[schema(description = "Complete information about a stored item including metadata and tags")] pub struct ItemInfo { - /// Item ID + /// Item ID. + /// + /// The unique identifier for the item in the database. #[schema(example = 42)] pub id: i64, - /// Timestamp + /// Timestamp. + /// + /// The creation timestamp of the item in ISO 8601 format. #[schema(example = "2023-12-01T15:30:45Z")] pub ts: String, - /// Size in bytes + /// Size in bytes. + /// + /// The size of the item's content in bytes, may be None if not set. #[schema(example = 1024)] pub size: Option, - /// Compression type + /// Compression type. + /// + /// The compression algorithm used for the item's content. #[schema(example = "gzip")] pub compression: String, - /// List of tags + /// List of tags. + /// + /// Vector of strings representing the tags associated with the item. #[schema(example = json!(["important", "work", "document"]))] pub tags: Vec, - /// Metadata hashmap + /// Metadata hashmap. + /// + /// Key-value pairs containing additional metadata about the item. #[schema(example = json!({"mime_type": "text/plain", "mime_encoding": "utf-8", "line_count": "42"}))] pub metadata: HashMap, } -/// Item information including content and metadata, with binary detection +/// 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. #[derive(Serialize, Deserialize, ToSchema)] #[schema(description = "Item information including content and metadata, with binary detection")] pub struct ItemContentInfo { - /// Metadata hashmap + /// Metadata hashmap. + /// + /// Key-value pairs of metadata, flattened into the structure. #[serde(flatten)] #[schema(example = json!({"mime_type": "text/plain", "mime_encoding": "utf-8", "line_count": "42"}))] pub metadata: HashMap, - /// Optional content as string + /// Optional content as string. + /// + /// The item's content as a string, only present if the content is text. #[schema(example = "Hello, world!\nThis is the content of the file.")] pub content: Option, - /// Binary content indicator + /// Binary content indicator. + /// + /// Boolean flag indicating whether the content is binary (true) or text (false). #[schema(example = false)] pub binary: bool, } -/// Query parameters for tags +/// Query parameters for tags. +/// +/// Structure for handling tag-based query parameters in API requests. #[derive(Debug, Deserialize)] pub struct TagsQuery { - /// Optional comma-separated tags + /// Optional comma-separated tags. + /// + /// String containing comma-separated tag names for filtering. pub tags: Option, } -/// Query parameters for listing items +/// Query parameters for listing items. +/// +/// Structure for pagination and sorting parameters in item listing endpoints. #[derive(Debug, Deserialize)] pub struct ListItemsQuery { - /// Optional comma-separated tags for filtering + /// Optional comma-separated tags for filtering. + /// + /// String containing tags to filter the item list. pub tags: Option, - /// Optional sort order + /// Optional sort order. + /// + /// String specifying sort direction: "newest" or "oldest". pub order: Option, - /// Optional pagination start index + /// Optional pagination start index. + /// + /// Unsigned integer indicating the starting index for pagination. pub start: Option, - /// Optional number of items to return + /// Optional number of items to return. + /// + /// Unsigned integer limiting the number of items returned. pub count: Option, } -/// Query parameters for item retrieval +/// Query parameters for item retrieval. +/// +/// Structure for content retrieval parameters, including binary handling and streaming options. #[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct ItemQuery { - /// Allow binary content (default: true) + /// Allow binary content (default: true). + /// + /// Boolean flag to allow or deny binary content in responses. #[serde(default = "default_allow_binary")] pub allow_binary: bool, - /// Byte offset (default: 0) + /// Byte offset (default: 0). + /// + /// Unsigned integer specifying the starting byte position for content retrieval. #[serde(default)] pub offset: u64, - /// Byte length (default: 0, meaning all) + /// Byte length (default: 0, meaning all). + /// + /// Unsigned integer specifying the maximum number of bytes to retrieve (0 = all remaining). #[serde(default)] pub length: u64, - /// Stream response (default: false) + /// Stream response (default: false). + /// + /// Boolean flag to enable streaming responses for large content. #[serde(default = "default_stream")] pub stream: bool, - /// Return as metadata JSON (default: false) + /// Return as metadata JSON (default: false). + /// + /// Boolean flag to return content and metadata in a structured JSON format. #[serde(default = "default_as_meta")] pub as_meta: bool, } -/// Query parameters for item content retrieval +/// Query parameters for item content retrieval. +/// +/// Extended query parameters for content-specific operations, including tag filtering. #[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct ItemContentQuery { - /// Optional comma-separated tags for filtering + /// Optional comma-separated tags for filtering. + /// + /// String containing tags to filter the item selection. pub tags: Option, - /// Allow binary content (default: true) + /// Allow binary content (default: true). + /// + /// Boolean flag to allow or deny binary content in responses. #[serde(default = "default_allow_binary")] pub allow_binary: bool, - /// Byte offset (default: 0) + /// Byte offset (default: 0). + /// + /// Unsigned integer specifying the starting byte position for content retrieval. #[serde(default)] pub offset: u64, - /// Byte length (default: 0, meaning all) + /// Byte length (default: 0, meaning all). + /// + /// Unsigned integer specifying the maximum number of bytes to retrieve (0 = all remaining). #[serde(default)] pub length: u64, - /// Stream response (default: false) + /// Stream response (default: false). + /// + /// Boolean flag to enable streaming responses for large content. #[serde(default = "default_stream")] pub stream: bool, - /// Return as metadata JSON (default: false) + /// Return as metadata JSON (default: false). + /// + /// Boolean flag to return content and metadata in a structured JSON format. #[serde(default = "default_as_meta")] pub as_meta: bool, } -/// Default function for allow_binary parameter +/// Default function for allow_binary parameter. +/// +/// # Returns +/// +/// `true` as the default value for allowing binary content. fn default_allow_binary() -> bool { true } -/// Default function for stream parameter +/// Default function for stream parameter. +/// +/// # Returns +/// +/// `false` as the default value for streaming responses. fn default_stream() -> bool { false } -/// Default function for as_meta parameter +/// Default function for as_meta parameter. +/// +/// # Returns +/// +/// `false` as the default value for metadata JSON responses. fn default_as_meta() -> bool { false } -/// Validates bearer authentication token +/// Validates bearer authentication token. +/// +/// This function checks if the provided authorization string is a valid Bearer token +/// matching the expected password or hash. /// /// # Arguments /// -/// * `auth_str` - The authorization string from the header -/// * `expected_password` - The expected plain text password -/// * `expected_hash` - Optional expected password hash +/// * `auth_str` - The authorization string from the header. +/// * `expected_password` - The expected plain text password. +/// * `expected_hash` - Optional expected password hash. /// /// # Returns /// -/// * `bool` - True if authentication succeeds, false otherwise +/// * `bool` - True if authentication succeeds, false otherwise. fn check_bearer_auth(auth_str: &str, expected_password: &str, expected_hash: &Option) -> bool { if !auth_str.starts_with("Bearer ") { return false; @@ -256,17 +418,20 @@ fn check_bearer_auth(auth_str: &str, expected_password: &str, expected_hash: &Op provided_password == expected_password } -/// Validates basic authentication credentials +/// Validates basic authentication credentials. +/// +/// This function decodes and validates Basic Auth credentials from the authorization +/// header against the expected password or hash. /// /// # Arguments /// -/// * `auth_str` - The authorization string from the header -/// * `expected_password` - The expected plain text password -/// * `expected_hash` - Optional expected password hash +/// * `auth_str` - The authorization string from the header. +/// * `expected_password` - The expected plain text password. +/// * `expected_hash` - Optional expected password hash. /// /// # Returns /// -/// * `bool` - True if authentication succeeds, false otherwise +/// * `bool` - True if authentication succeeds, false otherwise. fn check_basic_auth(auth_str: &str, expected_password: &str, expected_hash: &Option) -> bool { if !auth_str.starts_with("Basic ") { return false; @@ -292,17 +457,20 @@ fn check_basic_auth(auth_str: &str, expected_password: &str, expected_hash: &Opt false } -/// Checks authorization header for valid credentials +/// Checks authorization header for valid credentials. +/// +/// This function inspects the HTTP Authorization header for valid Bearer or Basic +/// authentication credentials against the provided password or hash. /// /// # Arguments /// -/// * `headers` - HTTP headers from the request -/// * `password` - Optional expected password -/// * `password_hash` - Optional expected password hash +/// * `headers` - HTTP headers from the request. +/// * `password` - Optional expected password. +/// * `password_hash` - Optional expected password hash. /// /// # Returns /// -/// * `bool` - True if authorization is valid, false otherwise +/// * `bool` - True if authorization is valid, false otherwise. pub fn check_auth(headers: &HeaderMap, password: &Option, password_hash: &Option) -> bool { // If neither password nor hash is set, no authentication required if password.is_none() && password_hash.is_none() { @@ -318,17 +486,20 @@ pub fn check_auth(headers: &HeaderMap, password: &Option, password_hash: false } -/// Middleware for logging requests and responses +/// Middleware for logging requests and responses. +/// +/// This middleware logs incoming requests and outgoing responses, including method, +/// URI, status code, response size, duration, and Accept header. /// /// # Arguments /// -/// * `ConnectInfo(addr)` - Connection information including client address -/// * `request` - The incoming HTTP request -/// * `next` - The next middleware in the chain +/// * `ConnectInfo(addr)` - Connection information including client address. +/// * `request` - The incoming HTTP request. +/// * `next` - The next middleware in the chain. /// /// # Returns /// -/// The response with logging applied +/// The response with logging applied. pub async fn logging_middleware( ConnectInfo(addr): ConnectInfo, request: Request, @@ -361,16 +532,20 @@ pub async fn logging_middleware( response } -/// Creates authentication middleware for the application +/// Creates authentication middleware for the application. +/// +/// This function returns a middleware that enforces authentication on protected routes +/// using Bearer token or Basic Auth, challenging unauthorized requests with appropriate +/// headers. /// /// # Arguments /// -/// * `password` - Optional plain text password for authentication -/// * `password_hash` - Optional hashed password for authentication +/// * `password` - Optional plain text password for authentication. +/// * `password_hash` - Optional hashed password for authentication. /// /// # Returns /// -/// An authentication middleware function that can be used with axum +/// An authentication middleware function that can be used with axum. pub fn create_auth_middleware( password: Option, password_hash: Option,