use crate::error::Result;
use std::time::Duration;
pub mod inmemory;
#[cfg(feature = "memcached")]
pub mod memcached;
#[cfg(feature = "redis")]
pub mod redis;
pub use inmemory::InMemoryBackend;
#[cfg(feature = "memcached")]
pub use memcached::{MemcachedBackend, MemcachedConfig};
#[cfg(feature = "redis")]
pub use redis::{PoolStats, RedisBackend, RedisConfig};
#[allow(async_fn_in_trait)]
pub trait CacheBackend: Send + Sync + Clone {
async fn get(&self, key: &str) -> Result<Option<Vec<u8>>>;
async fn set(&self, key: &str, value: Vec<u8>, ttl: Option<Duration>) -> Result<()>;
async fn delete(&self, key: &str) -> Result<()>;
async fn exists(&self, key: &str) -> Result<bool> {
Ok(self.get(key).await?.is_some())
}
async fn mget(&self, keys: &[&str]) -> Result<Vec<Option<Vec<u8>>>> {
let mut results = Vec::with_capacity(keys.len());
for key in keys {
results.push(self.get(key).await?);
}
Ok(results)
}
async fn mdelete(&self, keys: &[&str]) -> Result<()> {
for key in keys {
self.delete(key).await?;
}
Ok(())
}
async fn health_check(&self) -> Result<bool> {
Ok(true)
}
async fn clear_all(&self) -> Result<()> {
Err(crate::error::Error::NotImplemented(
"clear_all not implemented for this backend".to_string(),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_backend_exists_default() {
let backend = InMemoryBackend::new();
backend
.set("key", vec![1, 2, 3], None)
.await
.expect("Failed to set key");
assert!(backend.exists("key").await.expect("Failed to check exists"));
assert!(!backend
.exists("nonexistent")
.await
.expect("Failed to check exists"));
}
}