1use crate::client::SynapClient;
14use crate::error::Result;
15use serde::{Deserialize, Serialize};
16use serde_json::json;
17
18#[derive(Clone)]
22pub struct SortedSetManager {
23 client: SynapClient,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ScoredMember {
29 pub member: String,
30 pub score: f64,
31}
32
33impl SortedSetManager {
34 pub(crate) fn new(client: SynapClient) -> Self {
36 Self { client }
37 }
38
39 pub async fn add<K, M>(&self, key: K, member: M, score: f64) -> Result<bool>
50 where
51 K: AsRef<str>,
52 M: AsRef<str>,
53 {
54 let payload = json!({
55 "key": key.as_ref(),
56 "member": member.as_ref(),
57 "score": score,
58 });
59
60 let response = self.client.send_command("sortedset.zadd", payload).await?;
61 Ok(response.get("added").and_then(|v| v.as_u64()).unwrap_or(0) > 0)
62 }
63
64 pub async fn add_multiple<K>(&self, key: K, members: Vec<ScoredMember>) -> Result<usize>
79 where
80 K: AsRef<str>,
81 {
82 let payload = json!({
83 "key": key.as_ref(),
84 "members": members.iter().map(|m| json!({
85 "member": m.member,
86 "score": m.score,
87 })).collect::<Vec<_>>(),
88 });
89
90 let response = self.client.send_command("sortedset.zadd", payload).await?;
91 Ok(response.get("added").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
92 }
93
94 pub async fn rem<K>(&self, key: K, members: Vec<String>) -> Result<usize>
96 where
97 K: AsRef<str>,
98 {
99 let payload = json!({
100 "key": key.as_ref(),
101 "members": members,
102 });
103
104 let response = self.client.send_command("sortedset.zrem", payload).await?;
105 Ok(response
106 .get("removed")
107 .and_then(|v| v.as_u64())
108 .unwrap_or(0) as usize)
109 }
110
111 pub async fn score<K, M>(&self, key: K, member: M) -> Result<Option<f64>>
113 where
114 K: AsRef<str>,
115 M: AsRef<str>,
116 {
117 let payload = json!({
118 "key": key.as_ref(),
119 "member": member.as_ref(),
120 });
121
122 let response = self
123 .client
124 .send_command("sortedset.zscore", payload)
125 .await?;
126 Ok(response.get("score").and_then(|v| v.as_f64()))
127 }
128
129 pub async fn card<K>(&self, key: K) -> Result<usize>
131 where
132 K: AsRef<str>,
133 {
134 let payload = json!({"key": key.as_ref()});
135 let response = self.client.send_command("sortedset.zcard", payload).await?;
136 Ok(response.get("count").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
137 }
138
139 pub async fn incr_by<K, M>(&self, key: K, member: M, increment: f64) -> Result<f64>
141 where
142 K: AsRef<str>,
143 M: AsRef<str>,
144 {
145 let payload = json!({
146 "key": key.as_ref(),
147 "member": member.as_ref(),
148 "increment": increment,
149 });
150
151 let response = self
152 .client
153 .send_command("sortedset.zincrby", payload)
154 .await?;
155 Ok(response
156 .get("score")
157 .and_then(|v| v.as_f64())
158 .unwrap_or(0.0))
159 }
160
161 pub async fn range<K>(
176 &self,
177 key: K,
178 start: i64,
179 stop: i64,
180 with_scores: bool,
181 ) -> Result<Vec<ScoredMember>>
182 where
183 K: AsRef<str>,
184 {
185 let payload = json!({
186 "key": key.as_ref(),
187 "start": start,
188 "stop": stop,
189 "withscores": with_scores,
190 });
191
192 let response = self
193 .client
194 .send_command("sortedset.zrange", payload)
195 .await?;
196
197 if let Some(members_val) = response.get("members") {
198 Ok(serde_json::from_value(members_val.clone()).unwrap_or_default())
199 } else {
200 Ok(Vec::new())
201 }
202 }
203
204 pub async fn rev_range<K>(
206 &self,
207 key: K,
208 start: i64,
209 stop: i64,
210 with_scores: bool,
211 ) -> Result<Vec<ScoredMember>>
212 where
213 K: AsRef<str>,
214 {
215 let payload = json!({
216 "key": key.as_ref(),
217 "start": start,
218 "stop": stop,
219 "withscores": with_scores,
220 });
221
222 let response = self
223 .client
224 .send_command("sortedset.zrevrange", payload)
225 .await?;
226
227 if let Some(members_val) = response.get("members") {
228 Ok(serde_json::from_value(members_val.clone()).unwrap_or_default())
229 } else {
230 Ok(Vec::new())
231 }
232 }
233
234 pub async fn rank<K, M>(&self, key: K, member: M) -> Result<Option<usize>>
236 where
237 K: AsRef<str>,
238 M: AsRef<str>,
239 {
240 let payload = json!({
241 "key": key.as_ref(),
242 "member": member.as_ref(),
243 });
244
245 let response = self.client.send_command("sortedset.zrank", payload).await?;
246 Ok(response
247 .get("rank")
248 .and_then(|v| v.as_u64())
249 .map(|v| v as usize))
250 }
251
252 pub async fn rev_rank<K, M>(&self, key: K, member: M) -> Result<Option<usize>>
254 where
255 K: AsRef<str>,
256 M: AsRef<str>,
257 {
258 let payload = json!({
259 "key": key.as_ref(),
260 "member": member.as_ref(),
261 });
262
263 let response = self
264 .client
265 .send_command("sortedset.zrevrank", payload)
266 .await?;
267 Ok(response
268 .get("rank")
269 .and_then(|v| v.as_u64())
270 .map(|v| v as usize))
271 }
272
273 pub async fn count<K>(&self, key: K, min: f64, max: f64) -> Result<usize>
275 where
276 K: AsRef<str>,
277 {
278 let payload = json!({
279 "key": key.as_ref(),
280 "min": min,
281 "max": max,
282 });
283
284 let response = self
285 .client
286 .send_command("sortedset.zcount", payload)
287 .await?;
288 Ok(response.get("count").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
289 }
290
291 pub async fn range_by_score<K>(
293 &self,
294 key: K,
295 min: f64,
296 max: f64,
297 with_scores: bool,
298 ) -> Result<Vec<ScoredMember>>
299 where
300 K: AsRef<str>,
301 {
302 let payload = json!({
303 "key": key.as_ref(),
304 "min": min,
305 "max": max,
306 "withscores": with_scores,
307 });
308
309 let response = self
310 .client
311 .send_command("sortedset.zrangebyscore", payload)
312 .await?;
313
314 if let Some(members_val) = response.get("members") {
315 Ok(serde_json::from_value(members_val.clone()).unwrap_or_default())
316 } else {
317 Ok(Vec::new())
318 }
319 }
320
321 pub async fn pop_min<K>(&self, key: K, count: usize) -> Result<Vec<ScoredMember>>
323 where
324 K: AsRef<str>,
325 {
326 let payload = json!({
327 "key": key.as_ref(),
328 "count": count,
329 });
330
331 let response = self
332 .client
333 .send_command("sortedset.zpopmin", payload)
334 .await?;
335
336 if let Some(members_val) = response.get("members") {
337 Ok(serde_json::from_value(members_val.clone()).unwrap_or_default())
338 } else {
339 Ok(Vec::new())
340 }
341 }
342
343 pub async fn pop_max<K>(&self, key: K, count: usize) -> Result<Vec<ScoredMember>>
345 where
346 K: AsRef<str>,
347 {
348 let payload = json!({
349 "key": key.as_ref(),
350 "count": count,
351 });
352
353 let response = self
354 .client
355 .send_command("sortedset.zpopmax", payload)
356 .await?;
357
358 if let Some(members_val) = response.get("members") {
359 Ok(serde_json::from_value(members_val.clone()).unwrap_or_default())
360 } else {
361 Ok(Vec::new())
362 }
363 }
364
365 pub async fn rem_range_by_rank<K>(&self, key: K, start: i64, stop: i64) -> Result<usize>
367 where
368 K: AsRef<str>,
369 {
370 let payload = json!({
371 "key": key.as_ref(),
372 "start": start,
373 "stop": stop,
374 });
375
376 let response = self
377 .client
378 .send_command("sortedset.zremrangebyrank", payload)
379 .await?;
380 Ok(response
381 .get("removed")
382 .and_then(|v| v.as_u64())
383 .unwrap_or(0) as usize)
384 }
385
386 pub async fn rem_range_by_score<K>(&self, key: K, min: f64, max: f64) -> Result<usize>
388 where
389 K: AsRef<str>,
390 {
391 let payload = json!({
392 "key": key.as_ref(),
393 "min": min,
394 "max": max,
395 });
396
397 let response = self
398 .client
399 .send_command("sortedset.zremrangebyscore", payload)
400 .await?;
401 Ok(response
402 .get("removed")
403 .and_then(|v| v.as_u64())
404 .unwrap_or(0) as usize)
405 }
406
407 pub async fn inter_store<D>(
424 &self,
425 destination: D,
426 keys: Vec<&str>,
427 weights: Option<Vec<f64>>,
428 aggregate: &str,
429 ) -> Result<usize>
430 where
431 D: AsRef<str>,
432 {
433 let payload = json!({
434 "destination": destination.as_ref(),
435 "keys": keys,
436 "weights": weights,
437 "aggregate": aggregate,
438 });
439
440 let response = self
441 .client
442 .send_command("sortedset.zinterstore", payload)
443 .await?;
444 Ok(response.get("count").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
445 }
446
447 pub async fn union_store<D>(
449 &self,
450 destination: D,
451 keys: Vec<&str>,
452 weights: Option<Vec<f64>>,
453 aggregate: &str,
454 ) -> Result<usize>
455 where
456 D: AsRef<str>,
457 {
458 let payload = json!({
459 "destination": destination.as_ref(),
460 "keys": keys,
461 "weights": weights,
462 "aggregate": aggregate,
463 });
464
465 let response = self
466 .client
467 .send_command("sortedset.zunionstore", payload)
468 .await?;
469 Ok(response.get("count").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
470 }
471
472 pub async fn diff_store<D>(&self, destination: D, keys: Vec<&str>) -> Result<usize>
474 where
475 D: AsRef<str>,
476 {
477 let payload = json!({
478 "destination": destination.as_ref(),
479 "keys": keys,
480 });
481
482 let response = self
483 .client
484 .send_command("sortedset.zdiffstore", payload)
485 .await?;
486 Ok(response.get("count").and_then(|v| v.as_u64()).unwrap_or(0) as usize)
487 }
488
489 pub async fn stats(&self) -> Result<SortedSetStats> {
491 let payload = json!({});
492 let response = self.client.send_command("sortedset.stats", payload).await?;
493 Ok(serde_json::from_value(response).unwrap_or_default())
494 }
495}
496
497#[derive(Debug, Clone, Default, Serialize, Deserialize)]
499pub struct SortedSetStats {
500 pub total_keys: usize,
501 pub total_members: usize,
502 pub avg_members_per_key: f64,
503 pub memory_bytes: usize,
504}