Skip to main content

ccstat_core/
error.rs

1//! Error types for ccstat
2//!
3//! This module defines the error types used throughout the ccstat library.
4//! All errors are derived from `thiserror` for convenient error handling
5//! and automatic `From` implementations.
6//!
7//! # Example
8//!
9//! ```
10//! use ccstat_core::error::{CcstatError, Result};
11//!
12//! fn example_function() -> Result<()> {
13//!     // This will automatically convert io::Error to CcstatError
14//!     let _file = std::fs::read_to_string("nonexistent.txt")?;
15//!     Ok(())
16//! }
17//! ```
18
19use std::path::PathBuf;
20use thiserror::Error;
21
22use crate::types::ModelName;
23
24/// Main error type for ccstat operations
25///
26/// This enum encompasses all possible errors that can occur during
27/// ccstat operations, from IO errors to parsing failures and network issues.
28#[derive(Error, Debug)]
29pub enum CcstatError {
30    /// IO error occurred
31    #[error("IO error: {0}")]
32    Io(#[from] std::io::Error),
33
34    /// JSON parsing error
35    #[error("JSON parsing error: {0}")]
36    Json(#[from] serde_json::Error),
37
38    /// No Claude data directories found
39    #[error("No Claude data directories found")]
40    NoClaudeDirectory,
41
42    /// Unknown model encountered
43    #[error("Unknown model: {0}")]
44    UnknownModel(ModelName),
45
46    /// Invalid date format
47    #[error("Invalid date format: {0}")]
48    InvalidDate(String),
49
50    /// Invalid timezone
51    #[error("Invalid timezone: {0}")]
52    InvalidTimezone(String),
53
54    /// Invalid token limit
55    #[error("Invalid token limit: {0}")]
56    InvalidTokenLimit(String),
57
58    /// Parse error with file context
59    #[error("Parse error in {file}: {error}")]
60    Parse {
61        /// The file that caused the error
62        file: PathBuf,
63        /// The error message
64        error: String,
65    },
66
67    /// Network error
68    #[error("Network error: {0}")]
69    Network(#[from] reqwest::Error),
70
71    /// Configuration error
72    #[error("Configuration error: {0}")]
73    Config(String),
74
75    /// Invalid argument
76    #[error("Invalid argument: {0}")]
77    InvalidArgument(String),
78
79    /// Duplicate entry found
80    #[error("Duplicate entry")]
81    DuplicateEntry,
82}
83
84/// Convenience type alias for Results in ccstat
85///
86/// This type alias makes it easier to work with Results throughout
87/// the codebase by providing a default error type.
88///
89/// # Example
90///
91/// ```
92/// use ccstat_core::Result;
93///
94/// fn process_data() -> Result<String> {
95///     Ok("Processed successfully".to_string())
96/// }
97/// ```
98pub type Result<T> = std::result::Result<T, CcstatError>;
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_error_display() {
106        let error = CcstatError::NoClaudeDirectory;
107        assert_eq!(error.to_string(), "No Claude data directories found");
108    }
109
110    #[test]
111    fn test_io_error_conversion() {
112        let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
113        let ccstat_error: CcstatError = io_error.into();
114        assert!(matches!(ccstat_error, CcstatError::Io(_)));
115    }
116}