1use redis::{AsyncCommands, ErrorKind, RedisError, RedisResult, Value};
4use redis::aio::MultiplexedConnection;
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8pub fn serialize_to_json<T: Serialize>(item: &T) -> Result<String, RedisError> {
10 serde_json::to_string(item).map_err(|e| RedisError::from((
11 ErrorKind::ClientError,
12 "JSON serialization error",
13 e.to_string()
14 )))
15}
16
17pub fn deserialize_from_json<T: DeserializeOwned>(json: &str) -> Result<T, RedisError> {
19 serde_json::from_str(json).map_err(|e| RedisError::from((
20 ErrorKind::ClientError,
21 "JSON deserialization error",
22 e.to_string()
23 )))
24}
25
26pub async fn get_items<T: DeserializeOwned>(
28 con: MultiplexedConnection,
29 key: &str
30) -> Result<Vec<T>, RedisError> {
31 let strings: Vec<String> = con.clone().hvals(key).await?;
32
33 let mut items = Vec::with_capacity(strings.len());
34 for json_str in strings {
35 items.push(deserialize_from_json(&json_str)?);
36 }
37
38 Ok(items)
39}
40
41pub async fn get_hash_item<T: DeserializeOwned>(
43 con: MultiplexedConnection,
44 key: &str,
45 field: &str
46) -> Result<Option<T>, RedisError> {
47 match con.clone().hget::<_, _, Option<String>>(key, field).await? {
48 Some(json_str) => Ok(Some(deserialize_from_json(&json_str)?)),
49 None => Ok(None),
50 }
51}
52
53pub async fn get_item<T: DeserializeOwned>(
55 con: MultiplexedConnection,
56 key: &str,
57) -> Result<Option<T>, RedisError> {
58 match con.clone().get::<_, Option<String>>(key).await? {
59 Some(json_str) => Ok(Some(deserialize_from_json(&json_str)?)),
60 None => Ok(None),
61 }
62}
63
64pub async fn insert_items<T, F>(
66 mut con: MultiplexedConnection,
67 key: &str,
68 items: &[T],
69 id_extractor: F,
70) -> RedisResult<Value>
71where
72 T: Serialize,
73 F: Fn(&T) -> String,
74{
75 let mut entries = Vec::with_capacity(items.len());
76
77 for item in items {
78 let field = id_extractor(item);
79 let value = serialize_to_json(item)?;
80 entries.push((field, value));
81 }
82
83 con.hset_multiple(key, &entries).await
84}