redis_utils/
converters.rs

1use crate::TxError;
2use async_trait::async_trait;
3use redis::aio::ConnectionLike;
4use redis::{AsyncCommands, Pipeline, RedisError, ToRedisArgs};
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8pub trait PipelineJsonSet<U> {
9    fn json_set<Key: ToRedisArgs, Val: Serialize>(
10        &mut self,
11        key: Key,
12        val: Val,
13    ) -> Result<&mut Self, TxError<U>>;
14}
15
16impl<U> PipelineJsonSet<U> for Pipeline {
17    fn json_set<Key: ToRedisArgs, Val: Serialize>(
18        &mut self,
19        key: Key,
20        val: Val,
21    ) -> Result<&mut Self, TxError<U>> {
22        Ok(self.set(
23            key,
24            serde_json::to_string(&val).map_err(TxError::Serialization)?,
25        ))
26    }
27}
28
29#[derive(Debug)]
30pub enum JsonSetError {
31    Serialization(serde_json::Error),
32    DbError(redis::RedisError),
33}
34
35impl From<RedisError> for JsonSetError {
36    fn from(err: RedisError) -> Self {
37        JsonSetError::DbError(err)
38    }
39}
40
41impl From<serde_json::Error> for JsonSetError {
42    fn from(err: serde_json::Error) -> Self {
43        JsonSetError::Serialization(err)
44    }
45}
46
47#[async_trait]
48pub trait JsonSet {
49    async fn json_set<Key: ToRedisArgs + Send + Sync, Val: Serialize + Send + Sync>(
50        &mut self,
51        key: Key,
52        val: Val,
53    ) -> Result<(), JsonSetError>;
54}
55
56#[async_trait]
57impl<C> JsonSet for C
58where
59    C: ConnectionLike + Send + Sync,
60{
61    async fn json_set<Key: ToRedisArgs + Send + Sync, Val: Serialize + Send + Sync>(
62        &mut self,
63        key: Key,
64        val: Val,
65    ) -> Result<(), JsonSetError> {
66        Ok(self.set(key, serde_json::to_string(&val)?).await?)
67    }
68}
69
70#[derive(Debug)]
71pub enum JsonGetError {
72    Serialization(serde_json::Error),
73    DbError(redis::RedisError),
74}
75
76impl From<RedisError> for JsonGetError {
77    fn from(err: RedisError) -> Self {
78        JsonGetError::DbError(err)
79    }
80}
81
82impl From<serde_json::Error> for JsonGetError {
83    fn from(err: serde_json::Error) -> Self {
84        JsonGetError::Serialization(err)
85    }
86}
87
88#[async_trait]
89pub trait JsonGet<Val> {
90    async fn json_get<Key: ToRedisArgs + Send + Sync>(
91        &mut self,
92        key: Key,
93    ) -> Result<Val, JsonGetError>;
94    async fn maybe_json_get<Key: ToRedisArgs + Send + Sync>(
95        &mut self,
96        key: Key,
97    ) -> Result<Option<Val>, JsonGetError>;
98    async fn json_mget<Key: ToRedisArgs + Send + Sync>(
99        &mut self,
100        key: Key,
101    ) -> Result<Vec<Val>, JsonGetError>;
102    async fn watch_json_mget<Key: ToRedisArgs + Send + Sync>(
103        &mut self,
104        key: Key,
105    ) -> Result<Vec<Val>, JsonGetError>;
106}
107
108/// ```no_run
109/// extern crate redis_utils;
110/// extern crate redis;
111///
112/// use serde::Deserialize;
113/// use redis::{RedisResult, AsyncCommands};
114/// use redis_utils::converters::JsonGet;
115///
116/// #[derive(Deserialize)]
117/// struct Person {
118///     name: String,
119///     age: u8,
120/// }
121///
122/// async fn json_demo() -> RedisResult<()> {
123///     let mut con = redis::Client::open("redis://127.0.0.1/")?.get_async_connection().await?;
124///     let a: Person = con.json_get("key").await.unwrap();
125///
126///     Ok(())
127/// }
128/// ```
129#[async_trait]
130impl<C, Val> JsonGet<Val> for C
131where
132    C: ConnectionLike + Send + Sync,
133    Val: DeserializeOwned,
134{
135    /// get -> deserialize it from json
136    async fn json_get<Key: ToRedisArgs + Send + Sync>(
137        &mut self,
138        key: Key,
139    ) -> Result<Val, JsonGetError> {
140        let val: String = self.get(key).await?;
141        Ok(serde_json::from_str(&val)?)
142    }
143
144    /// get -> deserialize it from json into an optional value
145    async fn maybe_json_get<Key: ToRedisArgs + Send + Sync>(
146        &mut self,
147        key: Key,
148    ) -> Result<Option<Val>, JsonGetError> {
149        let val: Option<String> = self.get(key).await?;
150        match val {
151            Some(string) => Ok(Some(serde_json::from_str(&string)?)),
152            None => Ok(None),
153        }
154    }
155
156    /// mget -> deserialize it from json into a vector of values
157    async fn json_mget<Key: ToRedisArgs + Send + Sync>(
158        &mut self,
159        keys: Key,
160    ) -> Result<Vec<Val>, JsonGetError> {
161        if keys.is_single_arg() {
162            Ok(self.maybe_json_get(keys).await?.into_iter().collect())
163        } else {
164            let strings: Vec<String> = self.get(keys).await?;
165            let mut values = vec![];
166            for string in strings {
167                values.push(serde_json::from_str(&string)?)
168            }
169            Ok(values)
170        }
171    }
172
173    /// watch -> mget -> deserialize it from json into a vector of values
174    async fn watch_json_mget<Key: ToRedisArgs + Send + Sync>(
175        &mut self,
176        key: Key,
177    ) -> Result<Vec<Val>, JsonGetError> {
178        redis::cmd("WATCH").arg(&key).query_async(self).await?;
179        Ok(self.json_mget(key).await?)
180    }
181}