/ backend / src / services / redis_service.rs
redis_service.rs
  1  use mobc::Pool;
  2  use mobc_redis::{redis::AsyncCommands, RedisConnectionManager};
  3  use rocket::serde::DeserializeOwned;
  4  use serde::Serialize;
  5  
  6  #[derive(Debug, thiserror::Error)]
  7  pub enum RedisError {
  8      #[error("An internal error has occured")]
  9      Internal,
 10      #[error("A redis error occured")]
 11      Redis,
 12      #[error("Failed to serialize/deserialize the value to/from the correct json type")]
 13      Serde,
 14  }
 15  
 16  pub async fn redis_get<T>(
 17      redis_pool: &Pool<RedisConnectionManager>,
 18      key: String,
 19  ) -> Result<T, RedisError>
 20  where
 21      T: DeserializeOwned,
 22  {
 23      let mut redis_conn = redis_pool.get().await.map_err(|err| {
 24          error!("Failed to get redis connection from pool, err {}", err);
 25          RedisError::Internal
 26      })?;
 27  
 28      let raw_result = redis_conn.get::<String, String>(key).await.map_err(|err| {
 29          error!("Failed to get from redis, err {}", err);
 30          RedisError::Redis
 31      })?;
 32  
 33      serde_json::from_str::<T>(&raw_result).map_err(|err| {
 34          error!("Failed to parse json value from redis, err {}", err);
 35          RedisError::Serde
 36      })
 37  }
 38  
 39  pub async fn redis_get_option<T>(
 40      redis_pool: &Pool<RedisConnectionManager>,
 41      key: String,
 42  ) -> Result<Option<T>, RedisError>
 43  where
 44      T: DeserializeOwned,
 45  {
 46      let mut redis_conn = redis_pool.get().await.map_err(|err| {
 47          error!("Failed to get redis connection from pool, err {}", err);
 48          RedisError::Internal
 49      })?;
 50  
 51      let Some(raw_result) = redis_conn
 52          .get::<String, Option<String>>(key)
 53          .await
 54          .inspect_err(|err| error!("Failed to get from redis, err {}", err))
 55          .map_err(|_| RedisError::Redis)?
 56      else {
 57          return Ok(None);
 58      };
 59  
 60      serde_json::from_str::<T>(&raw_result)
 61          .inspect_err(|err| error!("Failed to parse json value from redis, err {}", err))
 62          .map_err(|_| RedisError::Serde)
 63          .map(Some)
 64  }
 65  
 66  pub async fn redis_set<T>(
 67      redis_pool: &Pool<RedisConnectionManager>,
 68      key: String,
 69      val: T,
 70      expiration_seconds: usize,
 71  ) -> Result<(), RedisError>
 72  where
 73      T: Serialize,
 74  {
 75      let mut redis_conn = redis_pool.get().await.map_err(|err| {
 76          error!("Failed to get redis connection from pool, err {}", err);
 77          RedisError::Internal
 78      })?;
 79  
 80      redis_conn
 81          .set_ex::<String, String, String>(
 82              key,
 83              serde_json::to_string(&val).map_err(|err| {
 84                  error!("Failed to serialize value, err {}", err);
 85                  RedisError::Serde
 86              })?,
 87              expiration_seconds,
 88          )
 89          .await
 90          .map_err(|err| {
 91              error!("Failed to insert value to redis, err {}", err);
 92              RedisError::Redis
 93          })?;
 94  
 95      Ok(())
 96  }
 97  
 98  pub async fn redis_push(
 99      redis_pool: &Pool<RedisConnectionManager>,
100      key: String,
101      value: String,
102  ) -> Result<(), RedisError> {
103      let mut redis_conn = redis_pool.get().await.map_err(|err| {
104          error!("Failed to get redis connection from pool, err {}", err);
105          RedisError::Internal
106      })?;
107  
108      redis_conn
109          .lpush::<String, String, usize>(key, value)
110          .await
111          .map_err(|err| {
112              error!("Failed to push value to redis, err {}", err);
113              RedisError::Redis
114          })?;
115  
116      Ok(())
117  }
118  
119  pub async fn redis_del(
120      redis_pool: &Pool<RedisConnectionManager>,
121      key: String,
122  ) -> Result<(), RedisError> {
123      let mut redis_conn = redis_pool.get().await.map_err(|err| {
124          error!("Failed to get redis connection from pool, err {}", err);
125          RedisError::Internal
126      })?;
127  
128      redis_conn.del::<String, ()>(key).await.map_err(|err| {
129          error!("Failed to delete value from redis, err {}", err);
130          RedisError::Redis
131      })?;
132  
133      Ok(())
134  }