docs: Add rustdoc to all files, document arguments and returns

Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-09-10 12:10:36 -03:00
parent c5f43b56f2
commit c965e9f51c
4 changed files with 442 additions and 121 deletions

View File

@@ -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<u16>,
/// 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<String>,
/// 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<String>,
}
/// 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<Mutex>
/// Database connection wrapped in Arc<Mutex>.
///
/// A thread-safe reference to the SQLite database connection, protected by a mutex
/// for concurrent access safety.
pub db: Arc<Mutex<rusqlite::Connection>>,
/// 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<ItemService>,
/// Command line argument parser
/// Command line argument parser.
///
/// Thread-safe reference to the Clap command builder for configuration access.
pub cmd: Arc<Mutex<clap::Command>>,
/// Application settings
/// Application settings.
///
/// Shared reference to the application's configuration settings.
pub settings: Arc<crate::config::Settings>,
}
/// 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<T> {
/// 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<T>,
/// Optional error message
/// Optional error message.
///
/// Error description, present only if the request failed.
pub error: Option<String>,
}
/// 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<Vec<ItemInfo>>,
/// Optional error message
/// Optional error message.
///
/// Error description if the request failed.
pub error: Option<String>,
}
/// 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<ItemInfo>,
/// Optional error message
/// Optional error message.
///
/// Error description if the request failed.
pub error: Option<String>,
}
/// 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<ItemContentInfo>,
/// Optional error message
/// Optional error message.
///
/// Error description if the request failed.
pub error: Option<String>,
}
/// 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<HashMap<String, String>>,
/// Optional error message
/// Optional error message.
///
/// Error description if the request failed.
pub error: Option<String>,
}
/// 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<crate::common::status::StatusInfo>,
/// Optional error message
/// Optional error message.
///
/// Error description if the request failed.
pub error: Option<String>,
}
/// 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<i64>,
/// 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<String>,
/// 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<String, String>,
}
/// 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<String, String>,
/// 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<String>,
/// 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<String>,
}
/// 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<String>,
/// Optional sort order
/// Optional sort order.
///
/// String specifying sort direction: "newest" or "oldest".
pub order: Option<String>,
/// Optional pagination start index
/// Optional pagination start index.
///
/// Unsigned integer indicating the starting index for pagination.
pub start: Option<u32>,
/// Optional number of items to return
/// Optional number of items to return.
///
/// Unsigned integer limiting the number of items returned.
pub count: Option<u32>,
}
/// 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<String>,
/// 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<String>) -> 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<String>) -> 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<String>, password_hash: &Option<String>) -> 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<String>, 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<SocketAddr>,
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<String>,
password_hash: Option<String>,