redis_om/json_model/
mod.rs1#[cfg(feature = "aio")]
2mod r#async;
3#[cfg(not(feature = "aio"))]
4mod sync;
5
6#[cfg(feature = "aio")]
7pub use r#async::JsonModel;
8#[cfg(not(feature = "aio"))]
9pub use sync::JsonModel;
10
11use redis::{ErrorKind, RedisError, RedisResult};
12
13mod cmds {
14 use crate::redis_model::RedisModel;
15 use redis::{Cmd, RedisResult};
16
17 pub fn save<D: serde::Serialize>(key: String, data: &D) -> RedisResult<Cmd> {
19 let mut cmd = redis::cmd("JSON.SET");
20
21 cmd.arg(key).arg("$").arg(serde_json::to_string(data)?);
22
23 Ok(cmd)
24 }
25
26 pub fn get<M: RedisModel>(pk: impl AsRef<str>) -> RedisResult<Cmd> {
28 let pk = pk.as_ref();
29
30 let mut cmd = redis::cmd("JSON.GET");
31
32 if M::_is_pk_fmt(pk) {
33 cmd.arg(pk);
34 } else {
35 cmd.arg(M::_fmt_pk(pk));
36 }
37
38 cmd.arg("$");
39
40 Ok(cmd)
41 }
42
43 pub fn all_pks<M: RedisModel>() -> RedisResult<Cmd> {
45 let pattern = format!("{}:*", M::_prefix_key());
46
47 let mut cmd = redis::cmd("SCAN");
48 cmd.cursor_arg(0).arg("MATCH").arg(pattern);
49
50 Ok(cmd)
51 }
52
53 pub fn delete<M: RedisModel>(pk: impl AsRef<str>) -> RedisResult<Cmd> {
55 let pk = pk.as_ref();
56
57 let mut cmd = redis::cmd("JSON.DEL");
58
59 if M::_is_pk_fmt(pk) {
60 cmd.arg(pk);
61 } else {
62 cmd.arg(M::_fmt_pk(pk));
63 }
64
65 cmd.arg("$");
66
67 Ok(cmd)
68 }
69}
70
71fn parse_from_get_resp<D: for<'de> serde::Deserialize<'de>>(resp: String) -> RedisResult<D> {
72 let value = serde_json::from_str::<'_, serde_json::Value>(&resp)
73 .map_err(RedisError::from)?
74 .as_array()
75 .and_then(|f| f.first())
76 .map(|v| v.to_owned())
77 .ok_or_else(|| {
78 RedisError::from((
79 ErrorKind::Serialize,
80 "expect an array with at least one item",
81 format!("got {:#?}", resp),
82 ))
83 })?;
84
85 serde_json::from_value(value).map_err(|e| e.into())
86}