use crate::error::Result;
use async_trait::async_trait;
use std::time::Duration;
#[async_trait]
#[allow(async_fn_in_trait)] pub trait Cache: Send + Sync {
async fn get_bytes(&self, key: &str) -> Result<Option<Vec<u8>>>;
async fn set_bytes(&self, key: &str, value: Vec<u8>, ttl: Option<Duration>) -> Result<()>;
async fn delete(&self, key: &str) -> Result<()>;
async fn clear(&self) -> Result<()>;
fn is_healthy(&self) -> bool;
}
pub trait CacheExt: Cache {
async fn get<T>(&self, key: &str) -> Result<Option<T>>
where
T: serde::de::DeserializeOwned,
{
if let Some(bytes) = self.get_bytes(key).await? {
serde_json::from_slice(&bytes).map(Some).map_err(|e| {
crate::error::TidewayError::internal(format!("Failed to deserialize: {}", e))
})
} else {
Ok(None)
}
}
async fn set<T>(&self, key: &str, value: &T, ttl: Option<Duration>) -> Result<()>
where
T: serde::Serialize + Send + Sync,
{
let bytes = serde_json::to_vec(value).map_err(|e| {
crate::error::TidewayError::internal(format!("Failed to serialize: {}", e))
})?;
self.set_bytes(key, bytes, ttl).await
}
async fn get_str(&self, key: &str) -> Result<Option<String>> {
self.get(key).await
}
async fn set_str(&self, key: &str, value: &str, ttl: Option<Duration>) -> Result<()> {
self.set(key, &value.to_string(), ttl).await
}
}
impl<T: Cache> CacheExt for T {}