use std::time::Duration;
use crate::{drivers::MemoryDriver, CacheError};
#[cfg(feature = "redis")]
use crate::drivers::RedisDriver;
#[derive(Clone)]
pub enum Driver {
Memory(MemoryDriver),
#[cfg(feature = "redis")]
Redis(RedisDriver),
}
impl Driver {
pub async fn get(&self, key: &str) -> Result<Option<String>, CacheError> {
match self {
Driver::Memory(d) => d.get(key).await,
#[cfg(feature = "redis")]
Driver::Redis(d) => d.get(key).await,
}
}
pub async fn set(
&self,
key: &str,
value: String,
ttl: Option<Duration>,
) -> Result<(), CacheError> {
match self {
Driver::Memory(d) => d.set(key, value, ttl).await,
#[cfg(feature = "redis")]
Driver::Redis(d) => d.set(key, value, ttl).await,
}
}
pub async fn forget(&self, key: &str) -> Result<(), CacheError> {
match self {
Driver::Memory(d) => d.forget(key).await,
#[cfg(feature = "redis")]
Driver::Redis(d) => d.forget(key).await,
}
}
pub async fn flush(&self) -> Result<(), CacheError> {
match self {
Driver::Memory(d) => d.flush().await,
#[cfg(feature = "redis")]
Driver::Redis(d) => d.flush().await,
}
}
}
pub fn build_driver(name: &str, redis_url: Option<&str>) -> Result<Driver, CacheError> {
match name {
#[cfg(feature = "redis")]
"redis" => {
let url = redis_url.ok_or(CacheError::MissingRedisUrl)?;
Ok(Driver::Redis(RedisDriver::new(url)?))
}
_ => Ok(Driver::Memory(MemoryDriver::new())),
}
}
#[derive(Clone)]
pub struct CacheHandle {
pub(crate) driver: Driver,
pub(crate) prefix: String,
}
impl CacheHandle {
pub fn new(driver: Driver, prefix: impl Into<String>) -> Self {
Self {
driver,
prefix: prefix.into(),
}
}
pub(crate) fn key(&self, k: &str) -> String {
if self.prefix.is_empty() {
k.to_string()
} else {
format!("{}{}", self.prefix, k)
}
}
}