sessions_redis/
lib.rs

1use std::{
2    fmt::Debug,
3    io::{Error, ErrorKind, Result},
4    time::Duration,
5};
6
7use redis::{aio::ConnectionLike, AsyncCommands};
8use sessions_core::{Data, Storage};
9
10#[derive(Clone, Debug)]
11pub struct RedisStorage<T> {
12    inner: T,
13}
14
15impl<T> RedisStorage<T> {
16    #[must_use]
17    pub fn new(client: T) -> Self {
18        Self { inner: client }
19    }
20
21    /// Gets a reference to the underlying client.
22    #[must_use]
23    pub fn get_ref(&self) -> &T {
24        &self.inner
25    }
26}
27
28impl<T> Storage for RedisStorage<T>
29where
30    T: ConnectionLike + Clone + Send + Sync,
31{
32    async fn get(&self, key: &str) -> Result<Option<Data>> {
33        Ok(serde_json::from_slice(
34            &self
35                .get_ref()
36                .clone()
37                .get::<&str, Vec<u8>>(key)
38                .await
39                .map_err(into_io_error)?,
40        )
41        .ok())
42    }
43
44    async fn set(&self, key: &str, val: Data, exp: &Duration) -> Result<()> {
45        self.get_ref()
46            .clone()
47            .set_ex(key, serde_json::to_vec(&val)?, exp.as_secs())
48            .await
49            .map_err(into_io_error)
50    }
51
52    async fn remove(&self, key: &str) -> Result<()> {
53        self.get_ref().clone().del(key).await.map_err(into_io_error)
54    }
55
56    async fn reset(&self) -> Result<()> {
57        redis::cmd("FLASHDB")
58            .query_async(&mut self.get_ref().clone())
59            .await
60            .map_err(into_io_error)
61    }
62}
63
64#[inline]
65fn into_io_error<E: std::error::Error + Send + Sync + 'static>(e: E) -> Error {
66    Error::new(ErrorKind::Other, e)
67}