use bb8::Pool;
use bb8_redis::RedisConnectionManager;
use redis::AsyncCommands;
use crate::rediska::config::RedisConfig;
pub struct Rediska {
pool: Pool<RedisConnectionManager>,
}
impl Rediska {
pub async fn new(config: RedisConfig) -> Result<Self, anyhow::Error> {
config.check()?;
let connection_url = if let Some(url) = &config.connection_url {
url.clone()
} else {
let password_part = if let Some(ref password) = config.password {
format!(":{}", password)
} else {
String::new()
};
let auth_part = if let Some(ref username) = config.username {
format!("{}{}", username, password_part)
} else {
password_part
};
format!(
"redis://{}@{}:{}/{}",
auth_part,
config.host.as_ref().unwrap(),
config.port.unwrap(),
config.db.unwrap_or(0)
)
};
let manager = RedisConnectionManager::new(connection_url)?;
let pool = Pool::builder()
.max_size(config.connection_pool_size)
.connection_timeout(config.connection_timeout)
.build(manager)
.await?;
Ok(Rediska { pool })
}
}
impl Rediska {
pub async fn conn(&self) -> anyhow::Result<bb8::PooledConnection<'_, RedisConnectionManager>> {
self.pool.get().await.map_err(anyhow::Error::from)
}
pub async fn set(&self, key: &str, value: &str, ttl: Option<u64>) -> anyhow::Result<()> {
let mut conn = self.pool.get().await?;
if let Some(seconds) = ttl {
let _: () = conn.set_ex(key, value, seconds).await?;
} else {
let _: () = conn.set(key, value).await?;
}
Ok(())
}
pub async fn get(&self, key: &str) -> anyhow::Result<Option<String>> {
let mut conn = self.pool.get().await?;
let value: Option<String> = conn.get(key).await?;
Ok(value)
}
}