use async_trait::async_trait;
use reinhardt_core::exception::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::Duration;
#[async_trait]
pub trait Cache: Send + Sync {
async fn get<T>(&self, key: &str) -> Result<Option<T>>
where
T: for<'de> Deserialize<'de> + Serialize + Send + Sync;
async fn set<T>(&self, key: &str, value: &T, ttl: Option<Duration>) -> Result<()>
where
T: Serialize + Send + Sync;
async fn delete(&self, key: &str) -> Result<()>;
async fn has_key(&self, key: &str) -> Result<bool>;
async fn clear(&self) -> Result<()>;
async fn get_many<T>(&self, keys: &[&str]) -> Result<HashMap<String, T>>
where
T: for<'de> Deserialize<'de> + Serialize + Send + Sync,
{
let mut results = HashMap::new();
for key in keys {
if let Some(value) = self.get::<T>(key).await? {
results.insert(key.to_string(), value);
}
}
Ok(results)
}
async fn set_many<T>(&self, values: HashMap<String, T>, ttl: Option<Duration>) -> Result<()>
where
T: Serialize + Send + Sync,
{
for (key, value) in values.iter() {
self.set(key, value, ttl).await?;
}
Ok(())
}
async fn delete_many(&self, keys: &[&str]) -> Result<()> {
for key in keys {
self.delete(key).await?;
}
Ok(())
}
async fn incr(&self, key: &str, delta: i64) -> Result<i64> {
let current: i64 = self.get(key).await?.unwrap_or(0);
let new_value = current + delta;
self.set(key, &new_value, None).await?;
Ok(new_value)
}
async fn decr(&self, key: &str, delta: i64) -> Result<i64> {
self.incr(key, -delta).await
}
}