use crate::cache::redis::AppRedis; use crate::error::AppError; use super::SessionKey; use super::format::{deserialize_session_state, serialize_session_state}; use super::interface::{SessionState, SessionStore}; use super::utils::generate_session_key; #[derive(Clone)] pub struct RedisSessionStore { redis: AppRedis, } impl RedisSessionStore { pub fn new(redis: AppRedis) -> Self { Self { redis } } } impl SessionStore for RedisSessionStore { async fn load(&self, session_key: &SessionKey) -> Result, AppError> { let mut conn = self.redis.get_connection(); let value: Option = redis::Cmd::new() .arg("GET") .arg(session_key.as_ref()) .query_async(&mut conn) .await?; match value { None => Ok(None), Some(v) => Ok(Some(deserialize_session_state(&v)?)), } } async fn save( &self, session_state: SessionState, ttl_secs: u64, ) -> Result { let body = serialize_session_state(&session_state)?; let session_key = generate_session_key(); let mut conn = self.redis.get_connection(); redis::Cmd::new() .arg("SETEX") .arg(session_key.as_ref()) .arg(ttl_secs) .arg(&body) .query_async::<()>(&mut conn) .await?; Ok(session_key) } async fn update( &self, session_key: SessionKey, session_state: SessionState, ttl_secs: u64, ) -> Result { let body = serialize_session_state(&session_state)?; let mut conn = self.redis.get_connection(); redis::Cmd::new() .arg("SETEX") .arg(session_key.as_ref()) .arg(ttl_secs) .arg(&body) .query_async::<()>(&mut conn) .await?; Ok(session_key) } async fn update_ttl(&self, session_key: &SessionKey, ttl_secs: u64) -> Result<(), AppError> { let mut conn = self.redis.get_connection(); redis::Cmd::new() .arg("EXPIRE") .arg(session_key.as_ref()) .arg(ttl_secs) .query_async::<()>(&mut conn) .await?; Ok(()) } async fn delete(&self, session_key: &SessionKey) -> Result<(), AppError> { let mut conn = self.redis.get_connection(); redis::Cmd::new() .arg("DEL") .arg(session_key.as_ref()) .query_async::<()>(&mut conn) .await?; Ok(()) } }