#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
use drivers::Driver;
use serde::{de::DeserializeOwned, Serialize};
use std::time::Duration;
pub mod drivers;
pub struct Cache<D: Driver> {
driver: D,
}
impl<D: Driver> Cache<D> {
pub async fn new(config: D::Config) -> Result<Self, D::Error> {
Ok(Self {
driver: D::new(config).await?,
})
}
pub async fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>, D::Error> {
self.driver.get(key).await
}
pub async fn has(&self, key: &str) -> Result<bool, D::Error> {
self.driver.has(key).await
}
pub async fn remember<T: Serialize + DeserializeOwned + Send + Sync>(
&mut self,
key: &str,
duration: Duration,
value: T,
) -> Result<T, D::Error> {
let value = if let Some(value) = self.driver.get::<T>(key).await? {
value
} else {
self.put(key, &value, duration).await?;
value
};
Ok(value)
}
pub async fn remember_forever<T: Serialize + DeserializeOwned + Send + Sync>(
&mut self,
key: &str,
value: T,
) -> Result<T, D::Error> {
let value = if let Some(value) = self.driver.get::<T>(key).await? {
value
} else {
self.forever(key, &value).await?;
value
};
Ok(value)
}
pub async fn pull<T: DeserializeOwned + Send>(
&mut self,
key: &str,
) -> Result<Option<T>, D::Error> {
let Some(item) = self.get(key).await? else {
return Ok(None);
};
self.forget(key).await?;
Ok(Some(item))
}
pub async fn put<T: Serialize + Sync>(
&mut self,
key: &str,
value: &T,
expiry: Duration,
) -> Result<(), D::Error> {
self.driver.put(key, value, Some(expiry)).await
}
pub async fn add<T: Serialize + Send + Sync>(
&mut self,
key: &str,
value: T,
expiry: Duration,
) -> Result<bool, D::Error> {
if self.has(key).await? {
return Ok(false);
}
self.put(key, &value, expiry).await?;
Ok(true)
}
pub async fn forever<T: Serialize + Send + Sync>(
&mut self,
key: &str,
value: T,
) -> Result<(), D::Error> {
self.driver.put(key, &value, None).await
}
pub async fn forget(&mut self, key: &str) -> Result<(), D::Error> {
self.driver.forget(key).await
}
pub async fn flush(&mut self) -> Result<(), D::Error> {
self.driver.flush().await
}
}