1use crate::client::SynapClient;
3use crate::error::Result;
4use serde_json::json;
5use std::collections::HashMap;
6
7#[derive(Clone)]
11pub struct HashManager {
12 client: SynapClient,
13}
14
15impl HashManager {
16 pub(crate) fn new(client: SynapClient) -> Self {
18 Self { client }
19 }
20
21 pub async fn set<K, F, V>(&self, key: K, field: F, value: V) -> Result<bool>
23 where
24 K: AsRef<str>,
25 F: AsRef<str>,
26 V: ToString,
27 {
28 let payload = json!({
29 "key": key.as_ref(),
30 "field": field.as_ref(),
31 "value": value.to_string(),
32 });
33
34 let response = self.client.send_command("hash.set", payload).await?;
35 Ok(response
36 .get("success")
37 .and_then(|v| v.as_bool())
38 .unwrap_or(false))
39 }
40
41 pub async fn get<K, F>(&self, key: K, field: F) -> Result<Option<String>>
43 where
44 K: AsRef<str>,
45 F: AsRef<str>,
46 {
47 let payload = json!({
48 "key": key.as_ref(),
49 "field": field.as_ref(),
50 });
51
52 let response = self.client.send_command("hash.get", payload).await?;
53 Ok(response
54 .get("value")
55 .and_then(|v| v.as_str())
56 .map(String::from))
57 }
58
59 pub async fn get_all<K>(&self, key: K) -> Result<HashMap<String, String>>
61 where
62 K: AsRef<str>,
63 {
64 let payload = json!({"key": key.as_ref()});
65 let response = self.client.send_command("hash.getall", payload).await?;
66
67 let fields = response
68 .get("fields")
69 .and_then(|v| serde_json::from_value(v.clone()).ok())
70 .unwrap_or_default();
71
72 Ok(fields)
73 }
74
75 pub async fn del<K, F>(&self, key: K, field: F) -> Result<i64>
77 where
78 K: AsRef<str>,
79 F: AsRef<str>,
80 {
81 let payload = json!({
82 "key": key.as_ref(),
83 "field": field.as_ref(),
84 "fields": [field.as_ref()],
85 });
86
87 let response = self.client.send_command("hash.del", payload).await?;
88 Ok(response
89 .get("deleted")
90 .and_then(|v| v.as_i64())
91 .unwrap_or(0))
92 }
93
94 pub async fn exists<K, F>(&self, key: K, field: F) -> Result<bool>
96 where
97 K: AsRef<str>,
98 F: AsRef<str>,
99 {
100 let payload = json!({
101 "key": key.as_ref(),
102 "field": field.as_ref(),
103 });
104
105 let response = self.client.send_command("hash.exists", payload).await?;
106 Ok(response
107 .get("exists")
108 .and_then(|v| v.as_bool())
109 .unwrap_or(false))
110 }
111
112 pub async fn keys<K>(&self, key: K) -> Result<Vec<String>>
114 where
115 K: AsRef<str>,
116 {
117 let payload = json!({"key": key.as_ref()});
118 let response = self.client.send_command("hash.keys", payload).await?;
119
120 let keys = response
121 .get("fields")
122 .and_then(|v| serde_json::from_value(v.clone()).ok())
123 .unwrap_or_default();
124
125 Ok(keys)
126 }
127
128 pub async fn values<K>(&self, key: K) -> Result<Vec<String>>
130 where
131 K: AsRef<str>,
132 {
133 let payload = json!({"key": key.as_ref()});
134 let response = self.client.send_command("hash.values", payload).await?;
135
136 let values = response
137 .get("values")
138 .and_then(|v| serde_json::from_value(v.clone()).ok())
139 .unwrap_or_default();
140
141 Ok(values)
142 }
143
144 pub async fn len<K>(&self, key: K) -> Result<usize>
146 where
147 K: AsRef<str>,
148 {
149 let payload = json!({"key": key.as_ref()});
150 let response = self.client.send_command("hash.len", payload).await?;
151 Ok(response.get("length").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
152 }
153
154 pub async fn mset<K>(&self, key: K, fields: HashMap<String, String>) -> Result<bool>
172 where
173 K: AsRef<str>,
174 {
175 let payload = json!({
177 "key": key.as_ref(),
178 "fields": fields,
179 });
180
181 let response = self.client.send_command("hash.mset", payload).await?;
182 Ok(response
183 .get("success")
184 .and_then(|v| v.as_bool())
185 .unwrap_or(false))
186 }
187
188 pub async fn mset_array<K>(&self, key: K, fields: Vec<(String, String)>) -> Result<bool>
203 where
204 K: AsRef<str>,
205 {
206 let fields_array: Vec<_> = fields
208 .into_iter()
209 .map(|(field, value)| {
210 json!({
211 "field": field,
212 "value": value,
213 })
214 })
215 .collect();
216
217 let payload = json!({
218 "key": key.as_ref(),
219 "fields": fields_array,
220 });
221
222 let response = self.client.send_command("hash.mset", payload).await?;
223 Ok(response
224 .get("success")
225 .and_then(|v| v.as_bool())
226 .unwrap_or(false))
227 }
228
229 pub async fn mget<K>(
231 &self,
232 key: K,
233 fields: Vec<String>,
234 ) -> Result<HashMap<String, Option<String>>>
235 where
236 K: AsRef<str>,
237 {
238 let payload = json!({
239 "key": key.as_ref(),
240 "fields": fields,
241 });
242
243 let response = self.client.send_command("hash.mget", payload).await?;
244
245 let values = response
246 .get("values")
247 .and_then(|v| serde_json::from_value(v.clone()).ok())
248 .unwrap_or_default();
249
250 Ok(values)
251 }
252
253 pub async fn incr_by<K, F>(&self, key: K, field: F, increment: i64) -> Result<i64>
255 where
256 K: AsRef<str>,
257 F: AsRef<str>,
258 {
259 let payload = json!({
260 "key": key.as_ref(),
261 "field": field.as_ref(),
262 "increment": increment,
263 });
264
265 let response = self.client.send_command("hash.incrby", payload).await?;
266 Ok(response.get("value").and_then(|v| v.as_i64()).unwrap_or(0))
267 }
268
269 pub async fn incr_by_float<K, F>(&self, key: K, field: F, increment: f64) -> Result<f64>
271 where
272 K: AsRef<str>,
273 F: AsRef<str>,
274 {
275 let payload = json!({
276 "key": key.as_ref(),
277 "field": field.as_ref(),
278 "increment": increment,
279 });
280
281 let response = self
282 .client
283 .send_command("hash.incrbyfloat", payload)
284 .await?;
285 Ok(response
286 .get("value")
287 .and_then(|v| v.as_f64())
288 .unwrap_or(0.0))
289 }
290
291 pub async fn set_nx<K, F, V>(&self, key: K, field: F, value: V) -> Result<bool>
293 where
294 K: AsRef<str>,
295 F: AsRef<str>,
296 V: ToString,
297 {
298 let payload = json!({
299 "key": key.as_ref(),
300 "field": field.as_ref(),
301 "value": value.to_string(),
302 });
303
304 let response = self.client.send_command("hash.setnx", payload).await?;
305 Ok(response
306 .get("created")
307 .and_then(|v| v.as_bool())
308 .unwrap_or(false))
309 }
310}