redis_om/json_model/
mod.rs

1#[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    /// Save data into redis database
18    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    /// Get a list of all primary keys for current type
27    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    /// Get a list of all primary keys for current type
44    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    /// Delete by given pk
54    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}