use std::time::Duration;
use deadpool_redis::redis::AsyncCommands;
use deadpool_redis::{Config, Pool, Runtime};
use crate::CacheError;
#[derive(Clone)]
pub struct RedisDriver {
pool: Pool,
}
impl RedisDriver {
pub fn new(url: &str) -> Result<Self, CacheError> {
let cfg = Config::from_url(url);
let pool = cfg
.create_pool(Some(Runtime::Tokio1))
.map_err(|e| CacheError::Redis(e.to_string()))?;
Ok(Self { pool })
}
pub async fn get(&self, key: &str) -> Result<Option<String>, CacheError> {
let mut conn = self
.pool
.get()
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
let value: Option<String> = conn
.get(key)
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
Ok(value)
}
pub async fn set(
&self,
key: &str,
value: String,
ttl: Option<Duration>,
) -> Result<(), CacheError> {
let mut conn = self
.pool
.get()
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
match ttl {
Some(d) => conn
.set_ex::<_, _, ()>(key, value, d.as_secs())
.await
.map_err(|e| CacheError::Redis(e.to_string()))?,
None => conn
.set::<_, _, ()>(key, value)
.await
.map_err(|e| CacheError::Redis(e.to_string()))?,
}
Ok(())
}
pub async fn forget(&self, key: &str) -> Result<(), CacheError> {
let mut conn = self
.pool
.get()
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
conn.del::<_, ()>(key)
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
Ok(())
}
pub async fn flush(&self) -> Result<(), CacheError> {
let mut conn = self
.pool
.get()
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
let _: () = deadpool_redis::redis::cmd("FLUSHDB")
.query_async(&mut *conn)
.await
.map_err(|e| CacheError::Redis(e.to_string()))?;
Ok(())
}
}