#![feature(box_into_inner)] use std::borrow::Cow; use async_trait::async_trait; pub use config::PluginConfig; use tracing::warn; #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Unable to connect")] Connect, #[error("Entry is invalid")] InvalidEntry, #[error("Can't invalidate keys {0:?}")] Invalidate(Vec), #[error("Failed to parse config")] InvalidConfig, } pub type CResult = Result; #[derive(Debug)] pub enum InvalidatePattern<'s> { StartsWith(Cow<'s, str>), EndsWith(Cow<'s, str>), Contains(Cow<'s, str>), Const(Cow<'s, str>), } pub struct CacheObject(pub Option>); impl CacheObject { pub fn into_inner(self) -> CResult> where T: serde::de::DeserializeOwned, { let Some(data) = self.0 else { return Ok(None) }; bincode::deserialize(&data) .map_err(|e| { warn!("Malformed cache entry: {e}"); Error::InvalidEntry }) .map(Some) } } #[async_trait] pub trait CacheAdapter { async fn new(config: PluginConfig) -> CResult where Self: Sized; async fn read(&self, key: &str) -> CResult; async fn set( &mut self, key: &str, data: &[u8], expires_in: Option, ) -> CResult<()>; async fn invalidate(&mut self, pattern: InvalidatePattern<'_>) -> CResult; async fn clear(&mut self) -> CResult; }