use thiserror::Error;
#[derive(Error, Debug)]
pub enum CacheError {
#[error("键 '{key}' 不存在")]
KeyNotFound { key: String },
#[error("键 '{key}' 已过期")]
KeyExpired { key: String },
#[error("序列化失败: {message}")]
SerializationError { message: String },
#[error("LZ4 压缩/解压缩失败: {message}")]
CompressionError { message: String },
#[cfg(feature = "melange-storage")]
#[error("MelangeDB 操作失败: {message}")]
MelangeDbError { message: String },
#[error("配置错误: {message}")]
ConfigError { message: String },
#[error("内存不足,无法分配 {requested_size} 字节")]
OutOfMemory { requested_size: usize },
#[error("缓存容量已满,当前大小: {current_size}, 最大容量: {max_capacity}")]
CacheFull {
current_size: usize,
max_capacity: usize,
},
#[error("无效的 TTL 值: {ttl_seconds} 秒")]
InvalidTtl { ttl_seconds: i64 },
#[error("并发访问冲突,键: '{key}'")]
ConcurrencyConflict { key: String },
#[error("IO 操作失败: {source}")]
IoError {
#[from]
source: std::io::Error,
},
#[error("未知错误: {message}")]
Other { message: String },
}
pub type CacheResult<T> = Result<T, CacheError>;
impl CacheError {
pub fn compression_error(message: impl Into<String>) -> Self {
Self::CompressionError {
message: message.into(),
}
}
pub fn config_error(message: impl Into<String>) -> Self {
Self::ConfigError {
message: message.into(),
}
}
pub fn other(message: impl Into<String>) -> Self {
Self::Other {
message: message.into(),
}
}
pub fn key_not_found(key: impl Into<String>) -> Self {
Self::KeyNotFound {
key: key.into(),
}
}
pub fn key_expired(key: impl Into<String>) -> Self {
Self::KeyExpired {
key: key.into(),
}
}
pub fn serialization_error(message: impl Into<String>) -> Self {
Self::Other {
message: format!("序列化错误: {}", message.into()),
}
}
#[cfg(feature = "melange-storage")]
pub fn melange_db_error(message: impl Into<String>) -> Self {
Self::MelangeDbError {
message: message.into(),
}
}
pub fn database_error(message: impl Into<String>) -> Self {
Self::Other {
message: format!("数据库错误: {}", message.into()),
}
}
pub fn out_of_memory(requested_size: usize) -> Self {
Self::OutOfMemory {
requested_size,
}
}
pub fn cache_full(current_size: usize, max_capacity: usize) -> Self {
Self::CacheFull {
current_size,
max_capacity,
}
}
pub fn invalid_ttl(ttl_seconds: i64) -> Self {
Self::InvalidTtl {
ttl_seconds,
}
}
pub fn concurrency_conflict(key: impl Into<String>) -> Self {
Self::ConcurrencyConflict {
key: key.into(),
}
}
pub fn io_error(message: impl Into<String>) -> Self {
Self::Other {
message: format!("IO错误: {}", message.into()),
}
}
pub fn is_key_not_found(&self) -> bool {
matches!(self, CacheError::KeyNotFound { .. })
}
pub fn is_key_expired(&self) -> bool {
matches!(self, CacheError::KeyExpired { .. })
}
pub fn is_cache_full(&self) -> bool {
matches!(self, CacheError::CacheFull { .. })
}
}