1use std::fmt;
7use std::io;
8
9#[derive(Debug)]
14pub enum CacheError {
15 KeyNotFound(String),
17
18 InvalidCommand(String),
20
21 ParseError(String),
23
24 IoError(io::Error),
26
27 CapacityExceeded { current: usize, max: usize },
29
30 InvalidKey(String),
32
33 InvalidValue(String),
35
36 LockError(String),
38}
39
40impl fmt::Display for CacheError {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 CacheError::KeyNotFound(key) => write!(f, "key not found: '{}'", key),
44 CacheError::InvalidCommand(cmd) => write!(f, "invalid command: '{}'", cmd),
45 CacheError::ParseError(msg) => write!(f, "parse error: {}", msg),
46 CacheError::IoError(err) => write!(f, "I/O error: {}", err),
47 CacheError::CapacityExceeded { current, max } => {
48 write!(f, "capacity exceeded: {} items (max: {})", current, max)
49 }
50 CacheError::InvalidKey(reason) => write!(f, "invalid key: {}", reason),
51 CacheError::InvalidValue(reason) => write!(f, "invalid value: {}", reason),
52 CacheError::LockError(msg) => write!(f, "lock error: {}", msg),
53 }
54 }
55}
56
57impl std::error::Error for CacheError {
58 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
59 match self {
60 CacheError::IoError(err) => Some(err),
61 _ => None,
62 }
63 }
64}
65
66impl From<io::Error> for CacheError {
67 fn from(err: io::Error) -> Self {
68 CacheError::IoError(err)
69 }
70}
71
72pub type CacheResult<T> = Result<T, CacheError>;
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_error_display() {
81 let err = CacheError::KeyNotFound("mykey".to_string());
82 assert_eq!(format!("{}", err), "key not found: 'mykey'");
83
84 let err = CacheError::InvalidCommand("foo".to_string());
85 assert_eq!(format!("{}", err), "invalid command: 'foo'");
86
87 let err = CacheError::CapacityExceeded {
88 current: 100,
89 max: 100,
90 };
91 assert_eq!(
92 format!("{}", err),
93 "capacity exceeded: 100 items (max: 100)"
94 );
95 }
96
97 #[test]
98 fn test_io_error_conversion() {
99 let io_err = io::Error::new(io::ErrorKind::ConnectionRefused, "connection refused");
100 let cache_err: CacheError = io_err.into();
101 assert!(matches!(cache_err, CacheError::IoError(_)));
102 }
103}