docs: document src/services/types.rs, src/modes/common.rs, and src/services/error.rs
Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
6
PLAN.md
6
PLAN.md
@@ -233,16 +233,16 @@ Private helpers (e.g., internal `fn` without `pub`) are not flagged, as they don
|
|||||||
40. **src/filter_parser.rs** (duplicate of filter_parser.rs)
|
40. **src/filter_parser.rs** (duplicate of filter_parser.rs)
|
||||||
- Same issues as above.
|
- Same issues as above.
|
||||||
|
|
||||||
41. **src/services/types.rs**
|
41. **src/services/types.rs** [DONE]
|
||||||
- `ItemWithMeta` and `ItemWithContent` structs: Partial.
|
- `ItemWithMeta` and `ItemWithContent` structs: Partial.
|
||||||
- `meta_as_map()` method: No doc.
|
- `meta_as_map()` method: No doc.
|
||||||
|
|
||||||
42. **src/modes/common.rs**
|
42. **src/modes/common.rs** [DONE]
|
||||||
- `OutputFormat` enum: No doc.
|
- `OutputFormat` enum: No doc.
|
||||||
- `ColumnType` enum: Partial.
|
- `ColumnType` enum: Partial.
|
||||||
- Functions (`get_meta_from_env`, `format_size`, etc.): Partial.
|
- Functions (`get_meta_from_env`, `format_size`, etc.): Partial.
|
||||||
|
|
||||||
43. **src/services/error.rs**
|
43. **src/services/error.rs** [DONE]
|
||||||
- `CoreError` enum: Partial variants.
|
- `CoreError` enum: Partial variants.
|
||||||
|
|
||||||
44. **src/services/compression_service.rs**
|
44. **src/services/compression_service.rs**
|
||||||
|
|||||||
@@ -26,17 +26,25 @@ use std::io::IsTerminal;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, strum::EnumString, strum::Display, PartialEq)]
|
||||||
|
#[strum(ascii_case_insensitive)]
|
||||||
/// Enum representing supported output formats for structured data.
|
/// Enum representing supported output formats for structured data.
|
||||||
///
|
///
|
||||||
/// Used to determine how to display lists, info, and status information.
|
/// Used to determine how to display lists, info, and status information in CLI modes.
|
||||||
|
/// Defaults to Table for human-readable output; JSON/YAML for machine parsing.
|
||||||
///
|
///
|
||||||
/// # Variants
|
/// # Variants
|
||||||
///
|
///
|
||||||
/// * `Table` - Formatted table output (default).
|
/// * `Table` - Formatted table output (default).
|
||||||
/// * `Json` - JSON structured output.
|
/// * `Json` - JSON structured output.
|
||||||
/// * `Yaml` - YAML structured output.
|
/// * `Yaml` - YAML structured output.
|
||||||
#[derive(Debug, Clone, strum::EnumString, strum::Display, PartialEq)]
|
///
|
||||||
#[strum(ascii_case_insensitive)]
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use keep::modes::common::OutputFormat;
|
||||||
|
/// assert_eq!(OutputFormat::from_str("json").unwrap(), OutputFormat::Json);
|
||||||
|
/// ```
|
||||||
pub enum OutputFormat {
|
pub enum OutputFormat {
|
||||||
Table,
|
Table,
|
||||||
Json,
|
Json,
|
||||||
@@ -46,16 +54,21 @@ pub enum OutputFormat {
|
|||||||
/// Extracts metadata from KEEP_META_* environment variables.
|
/// Extracts metadata from KEEP_META_* environment variables.
|
||||||
///
|
///
|
||||||
/// Scans environment for variables prefixed with KEEP_META_ and extracts
|
/// Scans environment for variables prefixed with KEEP_META_ and extracts
|
||||||
/// key-value pairs for initial item metadata.
|
/// key-value pairs for initial item metadata. Ignores KEEP_META_PLUGINS.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `HashMap<String, String>` - Metadata from environment variables.
|
/// `HashMap<String, String>` - Metadata from environment variables, with keys in uppercase without prefix.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// None; silently ignores non-matching vars and PLUGINS.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use std::env;
|
/// # use std::env;
|
||||||
|
/// # use std::collections::HashMap;
|
||||||
/// env::set_var("KEEP_META_COMMAND", "ls -la");
|
/// env::set_var("KEEP_META_COMMAND", "ls -la");
|
||||||
/// let meta = get_meta_from_env();
|
/// let meta = get_meta_from_env();
|
||||||
/// assert_eq!(meta.get("COMMAND"), Some(&"ls -la".to_string()));
|
/// assert_eq!(meta.get("COMMAND"), Some(&"ls -la".to_string()));
|
||||||
@@ -79,14 +92,16 @@ pub fn get_meta_from_env() -> HashMap<String, String> {
|
|||||||
|
|
||||||
/// Formats a file size in bytes to human-readable or raw format.
|
/// Formats a file size in bytes to human-readable or raw format.
|
||||||
///
|
///
|
||||||
|
/// Uses the humansize crate for human-readable output with decimal units (KB, MB, etc.).
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `size` - Size in bytes.
|
/// * `size` - Size in bytes as u64.
|
||||||
/// * `human_readable` - If true, use units like KB, MB; otherwise, raw bytes.
|
/// * `human_readable` - If true, use units like KB, MB; otherwise, raw bytes as string.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `String` - Formatted size string.
|
/// `String` - Formatted size string, e.g., "1.0K" or "1024".
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@@ -101,9 +116,11 @@ pub fn format_size(size: u64, human_readable: bool) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString)]
|
||||||
|
#[strum(ascii_case_insensitive)]
|
||||||
/// Enum representing column types for table display.
|
/// Enum representing column types for table display.
|
||||||
///
|
///
|
||||||
/// Defines standard and meta columns for list/info modes.
|
/// Defines standard and meta columns for list/info modes. Supports "meta:<name>" for specific metadata columns.
|
||||||
///
|
///
|
||||||
/// # Variants
|
/// # Variants
|
||||||
///
|
///
|
||||||
@@ -115,8 +132,14 @@ pub fn format_size(size: u64, human_readable: bool) -> String {
|
|||||||
/// * `FilePath` - File path column.
|
/// * `FilePath` - File path column.
|
||||||
/// * `Tags` - Tags column.
|
/// * `Tags` - Tags column.
|
||||||
/// * `Meta` - Metadata column (with sub-type via string parsing).
|
/// * `Meta` - Metadata column (with sub-type via string parsing).
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString)]
|
///
|
||||||
#[strum(ascii_case_insensitive)]
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use keep::modes::common::ColumnType;
|
||||||
|
/// assert_eq!(ColumnType::from_str("id").unwrap(), ColumnType::Id);
|
||||||
|
/// assert_eq!(ColumnType::from_str("meta:hostname").unwrap(), ColumnType::Meta);
|
||||||
|
/// ```
|
||||||
pub enum ColumnType {
|
pub enum ColumnType {
|
||||||
Id,
|
Id,
|
||||||
Time,
|
Time,
|
||||||
@@ -131,18 +154,22 @@ pub enum ColumnType {
|
|||||||
impl ColumnType {
|
impl ColumnType {
|
||||||
/// Parses a string to a ColumnType, handling "meta:<name>" pattern.
|
/// Parses a string to a ColumnType, handling "meta:<name>" pattern.
|
||||||
///
|
///
|
||||||
|
/// Supports direct enum variants or "meta:<name>" for metadata columns.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `s` - Input string to parse.
|
/// * `s` - Input string to parse, e.g., "size" or "meta:hostname".
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// * `anyhow::Result<ColumnType>` - Parsed type or error.
|
/// * `Ok(ColumnType)` - Parsed type on success.
|
||||||
|
/// * `Err(anyhow::Error)` - If the string doesn't match any variant.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let meta = ColumnType::from_str("meta:hostname")?;
|
/// use keep::modes::common::ColumnType;
|
||||||
|
/// let meta = ColumnType::from_str("meta:hostname").unwrap();
|
||||||
/// assert_eq!(meta, ColumnType::Meta);
|
/// assert_eq!(meta, ColumnType::Meta);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_str(s: &str) -> anyhow::Result<Self> {
|
pub fn from_str(s: &str) -> anyhow::Result<Self> {
|
||||||
@@ -244,15 +271,22 @@ pub fn settings_compression_type(cmd: &mut Command, settings: &config::Settings)
|
|||||||
|
|
||||||
/// Parses output format from settings.
|
/// Parses output format from settings.
|
||||||
///
|
///
|
||||||
/// Defaults to `Table` if not specified or invalid.
|
/// Defaults to `Table` if not specified or invalid. Uses case-insensitive string parsing.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `settings` - Application settings.
|
/// * `settings` - Application settings with optional output_format field.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `OutputFormat` - Parsed or default format.
|
/// `OutputFormat` - Parsed enum variant or Table as default.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let format = settings_output_format(&settings);
|
||||||
|
/// assert_eq!(format, OutputFormat::Json); // If settings.output_format = Some("json")
|
||||||
|
/// ```
|
||||||
pub fn settings_output_format(settings: &config::Settings) -> OutputFormat {
|
pub fn settings_output_format(settings: &config::Settings) -> OutputFormat {
|
||||||
settings.output_format
|
settings.output_format
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -262,15 +296,15 @@ pub fn settings_output_format(settings: &config::Settings) -> OutputFormat {
|
|||||||
|
|
||||||
/// Trims trailing whitespace from each line in a multi-line string.
|
/// Trims trailing whitespace from each line in a multi-line string.
|
||||||
///
|
///
|
||||||
/// Useful for cleaning up table output before printing.
|
/// Useful for cleaning up table output before printing. Preserves newlines but removes spaces/tabs at line ends.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `s` - Input string with potential trailing whitespace.
|
/// * `s` - Input string with potential trailing whitespace, e.g., "line1 \nline2 ".
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `String` - Cleaned string with trimmed lines.
|
/// `String` - Cleaned string with trimmed lines, e.g., "line1\nline2".
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,22 +1,44 @@
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Core error types used across services for consistent error handling.
|
/// Core error types used across services for consistent error handling.
|
||||||
|
///
|
||||||
|
/// This enum centralizes errors from database, I/O, validation, and other operations.
|
||||||
|
/// It implements Error and Debug for propagation and logging. Use this for all service-level errors.
|
||||||
|
///
|
||||||
|
/// # Variants
|
||||||
|
///
|
||||||
|
/// * `Database(rusqlite::Error)` - Wraps SQLite errors from queries or transactions.
|
||||||
|
/// * `Io(std::io::Error)` - Wraps I/O errors from file operations or streams.
|
||||||
|
/// * `ItemNotFound(i64)` - Specific item not found by ID.
|
||||||
|
/// * `ItemNotFoundGeneric` - Generic item not found (no ID specified).
|
||||||
|
/// * `InvalidInput(String)` - User or config input validation failure with message.
|
||||||
|
/// * `Compression(String)` - Compression/decompression errors with details.
|
||||||
|
/// * `Other(anyhow::Error)` - Catch-all for other anyhow-wrapped errors.
|
||||||
|
/// * `Migration(rusqlite_migration::Error)` - Database migration failures.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum CoreError {
|
pub enum CoreError {
|
||||||
#[error("Database error: {0}")]
|
#[error("Database error: {0}")]
|
||||||
|
/// Database operation failed.
|
||||||
Database(#[from] rusqlite::Error),
|
Database(#[from] rusqlite::Error),
|
||||||
#[error("I/O error: {0}")]
|
#[error("I/O error: {0}")]
|
||||||
|
/// File or stream I/O operation failed.
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
#[error("Item not found with id {0}")]
|
#[error("Item not found with id {0}")]
|
||||||
|
/// Item with the specified ID does not exist in the database.
|
||||||
ItemNotFound(i64),
|
ItemNotFound(i64),
|
||||||
#[error("Item not found")]
|
#[error("Item not found")]
|
||||||
|
/// Item does not exist (no specific ID).
|
||||||
ItemNotFoundGeneric,
|
ItemNotFoundGeneric,
|
||||||
#[error("Invalid input: {0}")]
|
#[error("Invalid input: {0}")]
|
||||||
|
/// Input validation failed.
|
||||||
InvalidInput(String),
|
InvalidInput(String),
|
||||||
#[error("Compression error: {0}")]
|
#[error("Compression error: {0}")]
|
||||||
|
/// Compression or decompression operation failed.
|
||||||
Compression(String),
|
Compression(String),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
/// Other unexpected error.
|
||||||
Other(#[from] anyhow::Error),
|
Other(#[from] anyhow::Error),
|
||||||
#[error("Migration error: {0}")]
|
#[error("Migration error: {0}")]
|
||||||
|
/// Database schema migration failed.
|
||||||
Migration(#[from] rusqlite_migration::Error),
|
Migration(#[from] rusqlite_migration::Error),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
/// Structure representing an item with its associated tags and metadata.
|
||||||
|
///
|
||||||
|
/// This is a composite type used for querying and displaying items with their relational data.
|
||||||
|
/// It combines the core Item with lists of Tags and Meta for complete item representation.
|
||||||
pub struct ItemWithMeta {
|
pub struct ItemWithMeta {
|
||||||
/// The core item data.
|
/// The core item data.
|
||||||
pub item: Item,
|
pub item: Item,
|
||||||
@@ -15,15 +19,30 @@ pub struct ItemWithMeta {
|
|||||||
impl ItemWithMeta {
|
impl ItemWithMeta {
|
||||||
/// Converts metadata to a HashMap for easy lookup.
|
/// Converts metadata to a HashMap for easy lookup.
|
||||||
///
|
///
|
||||||
|
/// This method transforms the vec of Meta into a simple key-value map,
|
||||||
|
/// useful for quick access by metadata name.
|
||||||
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `HashMap<String, String>` - Metadata as key-value pairs.
|
/// `HashMap<String, String>` - Metadata as key-value pairs, where keys are names and values are strings.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let item_with_meta = ItemWithMeta { /* ... */ };
|
||||||
|
/// let meta_map = item_with_meta.meta_as_map();
|
||||||
|
/// assert_eq!(meta_map.get("hostname"), Some(&"example.com".to_string()));
|
||||||
|
/// ```
|
||||||
pub fn meta_as_map(&self) -> HashMap<String, String> {
|
pub fn meta_as_map(&self) -> HashMap<String, String> {
|
||||||
self.meta.iter().cloned().map(|m| (m.name, m.value)).collect()
|
self.meta.iter().cloned().map(|m| (m.name, m.value)).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
/// Structure representing an item with its content, tags, and metadata.
|
||||||
|
///
|
||||||
|
/// This extends ItemWithMeta by including the actual content bytes, suitable for full item retrieval
|
||||||
|
/// including binary or text data. Note: For large content, consider streaming alternatives.
|
||||||
pub struct ItemWithContent {
|
pub struct ItemWithContent {
|
||||||
/// Item with associated metadata and tags.
|
/// Item with associated metadata and tags.
|
||||||
pub item_with_meta: ItemWithMeta,
|
pub item_with_meta: ItemWithMeta,
|
||||||
|
|||||||
Reference in New Issue
Block a user