use async_trait::async_trait;
use std::time::Duration;
use thiserror::Error;
pub type StorageResult<T> = Result<T, StorageError>;
#[derive(Debug, Error)]
pub enum StorageError {
#[error("Storage operation failed: {0}")]
OperationFailed(String),
#[error("Key not found: {0}")]
KeyNotFound(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Connection error: {0}")]
ConnectionError(String),
#[error("Internal error: {0}")]
InternalError(String),
}
#[async_trait]
pub trait SaStorage: Send + Sync {
async fn get(&self, key: &str) -> StorageResult<Option<String>>;
async fn set(&self, key: &str, value: &str, ttl: Option<Duration>) -> StorageResult<()>;
async fn delete(&self, key: &str) -> StorageResult<()>;
async fn exists(&self, key: &str) -> StorageResult<bool>;
async fn expire(&self, key: &str, ttl: Duration) -> StorageResult<()>;
async fn ttl(&self, key: &str) -> StorageResult<Option<Duration>>;
async fn mget(&self, keys: &[&str]) -> StorageResult<Vec<Option<String>>> {
let mut results = Vec::with_capacity(keys.len());
for key in keys {
results.push(self.get(key).await?);
}
Ok(results)
}
async fn mset(&self, items: &[(&str, &str)], ttl: Option<Duration>) -> StorageResult<()> {
for (key, value) in items {
self.set(key, value, ttl).await?;
}
Ok(())
}
async fn mdel(&self, keys: &[&str]) -> StorageResult<()> {
for key in keys {
self.delete(key).await?;
}
Ok(())
}
async fn incr(&self, key: &str) -> StorageResult<i64> {
let current = self.get(key).await?
.and_then(|v| v.parse::<i64>().ok())
.unwrap_or(0);
let new_value = current + 1;
self.set(key, &new_value.to_string(), None).await?;
Ok(new_value)
}
async fn decr(&self, key: &str) -> StorageResult<i64> {
let current = self.get(key).await?
.and_then(|v| v.parse::<i64>().ok())
.unwrap_or(0);
let new_value = current - 1;
self.set(key, &new_value.to_string(), None).await?;
Ok(new_value)
}
async fn clear(&self) -> StorageResult<()>;
async fn keys(&self, _pattern: &str) -> StorageResult<Vec<String>> {
Ok(Vec::new())
}
}