use crate::errors::*;
use opendal::Operator;
use opendal::layers::LoggingLayer;
use opendal::services::Redis;
use std::collections::HashMap;
use std::time::Duration;
use url::Url;
pub struct RedisCache;
impl RedisCache {
pub fn build_from_url(url: &str, key_prefix: &str, ttl: u64) -> Result<Operator> {
let parsed = Url::parse(url)?;
let mut builder = Redis::default()
.endpoint(parsed.as_str())
.username(parsed.username())
.password(parsed.password().unwrap_or_default())
.root(key_prefix);
if ttl != 0 {
builder = builder.default_ttl(Duration::from_secs(ttl));
}
let options: HashMap<_, _> = parsed
.query_pairs()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
builder = builder.db(options
.get("db")
.map(|v| v.parse().unwrap_or_default())
.unwrap_or_default());
let op = Operator::new(builder)?
.layer(LoggingLayer::default())
.finish();
Ok(op)
}
pub fn build_single(
endpoint: &str,
username: Option<&str>,
password: Option<&str>,
db: u32,
key_prefix: &str,
ttl: u64,
) -> Result<Operator> {
let builder = Redis::default().endpoint(endpoint);
Self::build_common(builder, username, password, db, key_prefix, ttl)
}
pub fn build_cluster(
endpoints: &str,
username: Option<&str>,
password: Option<&str>,
db: u32,
key_prefix: &str,
ttl: u64,
) -> Result<Operator> {
let builder = Redis::default().cluster_endpoints(endpoints);
Self::build_common(builder, username, password, db, key_prefix, ttl)
}
fn build_common(
mut builder: Redis,
username: Option<&str>,
password: Option<&str>,
db: u32,
key_prefix: &str,
ttl: u64,
) -> Result<Operator> {
builder = builder
.username(username.unwrap_or_default())
.password(password.unwrap_or_default())
.db(db.into())
.root(key_prefix);
if ttl != 0 {
builder = builder.default_ttl(Duration::from_secs(ttl));
}
let op = Operator::new(builder)?
.layer(LoggingLayer::default())
.finish();
Ok(op)
}
}