pouch_sdk/
command.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Result;
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(tag = "action")]
7pub enum Command {
8    #[serde(rename = "GET")]
9    Get {
10        #[serde(rename = "key")]
11        key: String,
12    },
13    #[serde(rename = "GETDEL")]
14    GetDel {
15        #[serde(rename = "key")]
16        key: String,
17    },
18    #[serde(rename = "SET")]
19    Set {
20        #[serde(rename = "key")]
21        key: String,
22
23        #[serde(rename = "value")]
24        value: String,
25
26        #[serde(rename = "expiry_seconds")]
27        expiry_seconds: u64,
28
29        #[serde(rename = "expiry_ts")]
30        #[serde(default)]
31        expiry_ts: u64,
32    },
33    #[serde(rename = "DELETE")]
34    Delete {
35        #[serde(rename = "keys")]
36        keys: Vec<String>,
37    },
38    #[serde(rename = "LPUSH")]
39    LPush {
40        #[serde(rename = "key")]
41        key: String,
42        #[serde(rename = "values")]
43        values: Vec<String>,
44    },
45    #[serde(rename = "RPUSH")]
46    RPush {
47        #[serde(rename = "key")]
48        key: String,
49        #[serde(rename = "values")]
50        values: Vec<String>,
51    },
52    #[serde(rename = "LRANGE")]
53    LRange {
54        #[serde(rename = "key")]
55        key: String,
56        #[serde(rename = "start")]
57        start: Option<usize>,
58        #[serde(rename = "end")]
59        end: Option<usize>,
60    },
61    #[serde(rename = "LLEN")]
62    LLen {
63        #[serde(rename = "key")]
64        key: String,
65    },
66    #[serde(rename = "LPOP")]
67    LPop {
68        #[serde(rename = "key")]
69        key: String,
70    },
71    #[serde(rename = "RPOP")]
72    RPop {
73        #[serde(rename = "key")]
74        key: String,
75    },
76    #[serde(rename = "EXISTS")]
77    Exists {
78        #[serde(rename = "key")]
79        key: String,
80    },
81    #[serde(rename = "INCR")]
82    Incr {
83        #[serde(rename = "key")]
84        key: String,
85    },
86    #[serde(rename = "INCRBY")]
87    IncrBy {
88        #[serde(rename = "key")]
89        key: String,
90        #[serde(rename = "increment")]
91        increment: i64,
92    },
93    #[serde(rename = "DECR")]
94    Decr {
95        #[serde(rename = "key")]
96        key: String,
97    },
98    #[serde(rename = "DECRBY")]
99    DecrBy {
100        #[serde(rename = "key")]
101        key: String,
102        #[serde(rename = "decrement")]
103        decrement: i64,
104    },
105    #[serde(rename = "SADD")]
106    SAdd {
107        #[serde(rename = "key")]
108        key: String,
109        #[serde(rename = "values")]
110        values: Vec<String>,
111    },
112    #[serde(rename = "SCARD")]
113    SCard {
114        #[serde(rename = "key")]
115        key: String,
116    },
117    #[serde(rename = "SINTER")]
118    SInter {
119        #[serde(rename = "key")]
120        key: String,
121        #[serde(rename = "others")]
122        others: Vec<String>,
123    },
124    #[serde(rename = "SDIFF")]
125    SDiff {
126        #[serde(rename = "key")]
127        key: String,
128        #[serde(rename = "others")]
129        others: Vec<String>,
130    },
131    #[serde(rename = "ZADD")]
132    ZAdd {
133        #[serde(rename = "key")]
134        key: String,
135        #[serde(rename = "values")]
136        values: HashMap<String, i64>,
137    },
138    #[serde(rename = "ZCARD")]
139    ZCard {
140        #[serde(rename = "key")]
141        key: String,
142    },
143}
144
145impl Command {
146    pub fn from_json(json_str: &str) -> Result<Command> {
147        serde_json::from_str(json_str)
148    }
149
150    pub(crate) fn to_json(&self) -> Result<String> {
151        serde_json::to_string(self)
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158
159    #[test]
160    fn test_get_command_from_json() {
161        let json_str = r#"{"action":"GET","key":"mykey"}"#;
162        let cmd = Command::from_json(json_str).unwrap();
163        match cmd {
164            Command::Get { key } => assert_eq!(key, "mykey"),
165            _ => panic!("Expected Command::Get"),
166        }
167    }
168
169    #[test]
170    fn test_set_command_to_json() {
171        let cmd = Command::Set {
172            key: "mykey".to_string(),
173            value: "myvalue".to_string(),
174            expiry_seconds: 3600,
175            expiry_ts: 0,
176        };
177        let json_str = cmd.to_json().unwrap();
178        assert_eq!(
179            json_str,
180            r#"{"action":"SET","key":"mykey","value":"myvalue","expiry_seconds":3600,"expiry_ts":0}"#
181        );
182    }
183
184    #[test]
185    fn test_zadd_command_from_json() {
186        let json_str = r#"{"action":"ZADD","key":"myset","values":{"key_1":1,"key_2":2}}"#;
187        let cmd = Command::from_json(json_str).unwrap();
188        match cmd {
189            Command::ZAdd { key, values } => {
190                assert_eq!(key, "myset");
191                assert_eq!(values.get("key_1"), Some(&1));
192                assert_eq!(values.get("key_2"), Some(&2));
193            }
194            _ => panic!("Expected Command::ZAdd"),
195        }
196    }
197
198    #[test]
199    fn test_lrange_command_to_json() {
200        let cmd = Command::LRange {
201            key: "mylist".to_string(),
202            start: Some(0),
203            end: Some(10),
204        };
205        let json_str = cmd.to_json().unwrap();
206        assert_eq!(
207            json_str,
208            r#"{"action":"LRANGE","key":"mylist","start":0,"end":10}"#
209        );
210    }
211}