gbserver/gb-storage/src/redis.rs
2024-12-26 10:09:39 -03:00

79 lines
No EOL
2.7 KiB
Rust

use gb_core::{Result, Error};
use redis::{Client, Commands};
use serde::{de::DeserializeOwned, Serialize};
use std::time::Duration;
use tracing::instrument;
pub struct RedisStorage {
client: Client,
}
impl RedisStorage {
pub fn new(url: &str) -> Result<Self> {
let client = Client::open(url)
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
Ok(Self { client })
}
#[allow(dependency_on_unit_never_type_fallback)]
#[instrument(skip(self))]
pub async fn set<T: Serialize + std::fmt::Debug>(&self, key: &str, value: &T) -> Result<()> {
let mut conn = self.client.get_connection()
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
let serialized = serde_json::to_string(value)
.map_err(|e| Error::internal(format!("Serialization error: {}", e)))?;
conn.set(key, serialized)
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
Ok(())
}
#[instrument(skip(self))]
pub async fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>> {
let mut conn = self.client.get_connection()
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
let value: Option<String> = conn.get(key)
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
match value {
Some(v) => {
let deserialized = serde_json::from_str(&v)
.map_err(|e| Error::internal(format!("Deserialization error: {}", e)))?;
Ok(Some(deserialized))
}
None => Ok(None)
}
}
#[instrument(skip(self))]
pub async fn delete(&self, key: &str) -> Result<bool> {
let mut conn = self.client.get_connection()
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
conn.del(key)
.map_err(|e| Error::internal(format!("Redis error: {}", e)))
}
#[allow(dependency_on_unit_never_type_fallback)]
#[instrument(skip(self))]
pub async fn set_with_ttl<T: Serialize + std::fmt::Debug>(&self, key: &str, value: &T, ttl: Duration) -> Result<()> {
let mut conn = self.client.get_connection()
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
let serialized = serde_json::to_string(value)
.map_err(|e| Error::internal(format!("Serialization error: {}", e)))?;
redis::pipe()
.set(key, serialized)
.expire(key, ttl.as_secs() as i64)
.query(&mut conn)
.map_err(|e| Error::internal(format!("Redis error: {}", e)))?;
Ok(())
}
}