use redis::{AsyncCommands, Client};
use std::time::Duration;
#[derive(Clone)]
pub struct Cache {
client: Client,
}
impl Cache {
pub async fn new(redis_url: &str) -> Result<Self, redis::RedisError> {
let client = Client::open(redis_url)?;
Ok(Cache { client })
}
pub async fn get<T: for<'de> serde::Deserialize<'de>>(&self, key: &str) -> Result<Option<T>, Box<dyn std::error::Error + Send + Sync>> {
let mut conn = self.client.get_async_connection().await?;
let value: Option<String> = conn.get(key).await?;
match value {
Some(v) => Ok(Some(serde_json::from_str(&v)?)),
None => Ok(None),
}
}
pub async fn set<T: serde::Serialize>(&self, key: &str, value: &T, ttl: Duration) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut conn = self.client.get_async_connection().await?;
let serialized = serde_json::to_string(value)?;
let _: () = conn.set_ex(key, serialized, ttl.as_secs() as usize).await?;
Ok(())
}
pub async fn delete(&self, key: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut conn = self.client.get_async_connection().await?;
let _: () = conn.del(key).await?;
Ok(())
}
}