use redis::Client;
use redis::aio::MultiplexedConnection;
use crate::error::{Result, RiftError, SystemReject};
#[derive(Clone)]
pub struct RedisPool {
conn: MultiplexedConnection,
url: String,
prefix: String,
}
impl RedisPool {
pub async fn connect(url: &str, prefix: &str) -> Result<Self> {
let client = Client::open(url)
.map_err(|e| RiftError::System(SystemReject::Internal(format!("redis client: {e}"))))?;
let conn = client
.get_multiplexed_async_connection()
.await
.map_err(|e| {
RiftError::System(SystemReject::Internal(format!("redis connect: {e}")))
})?;
Ok(Self {
conn,
url: url.to_string(),
prefix: prefix.to_string(),
})
}
pub fn conn(&self) -> &MultiplexedConnection {
&self.conn
}
pub fn sync_cmd<F, T>(&self, f: F) -> T
where
F: FnOnce(&mut redis::Connection) -> redis::RedisResult<T>,
{
let mut conn = redis::Client::open(&*self.url)
.and_then(|c| c.get_connection())
.unwrap_or_else(|e| panic!("redis sync connect: {e}"));
f(&mut conn).unwrap_or_else(|e| panic!("redis sync cmd: {e}"))
}
pub fn key(&self, suffix: &str) -> String {
format!("{}:{suffix}", self.prefix)
}
pub fn topic_key(&self, kind: &str, topic: &str) -> String {
format!("{}:{kind}:{topic}", self.prefix)
}
pub fn prefix(&self) -> &str {
&self.prefix
}
pub fn url(&self) -> &str {
&self.url
}
}
impl std::fmt::Debug for RedisPool {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RedisPool")
.field("url", &self.url)
.field("prefix", &self.prefix)
.finish()
}
}