tetrio_api/http/caches/
redis_cache.rs1use std::{borrow::Cow, fmt::Debug};
2
3use async_trait::async_trait;
4use redis::Commands;
5use serde::{de::DeserializeOwned, Serialize};
6
7use crate::{http::error::Error, models::packet::{Packet, SuccessPacket}};
8
9use super::cache::CacheHandler;
10
11pub struct RedisCache<'a> {
13 pub client: Cow<'a, redis::Client>
14}
15
16impl<'a> RedisCache<'a> {
17 pub fn new(client: Cow<'a, redis::Client>) -> Self {
18 Self {
19 client
20 }
21 }
22}
23
24#[async_trait]
25impl<'a, ErrorT: std::error::Error + Sync + Send + Debug> CacheHandler<ErrorT> for RedisCache<'a> {
26 type CachingError = redis::RedisError;
27 async fn try_get_cache<T: DeserializeOwned + Serialize>(&self, key: &str) -> Result<Option<Packet<T>>, Error<ErrorT, Self::CachingError>>
28 {
29 let mut con = self.client.get_connection().map_err(Error::CachingError)?;
30
31 let exists: bool = con.exists(key).map_err(Error::CachingError)?;
32
33 match exists {
34 false => Ok(None),
35 true => Ok(Some(serde_json::from_str(&con.get::<&str, String>(key).map_err(Error::CachingError)?).map_err(Error::CacheConversionError)?))
36 }
37 }
38
39 async fn cache_value<T: DeserializeOwned + Serialize + Send + Sync>(&self, key: &str, value: SuccessPacket<T>) -> Result<(), Error<ErrorT, Self::CachingError>> {
40 let mut con = self.client.get_connection().map_err(Error::CachingError)?;
41
42 con.set_ex::<_, _, redis::Value>(key, serde_json::to_string(&value).map_err(Error::CacheConversionError)?, value.cache.time_until_elapsed().as_secs()).map_err(Error::CachingError)?;
43
44 Ok(())
45 }
46
47}