rustis/commands/sorted_set_commands.rs
1use crate::{
2 client::{PreparedCommand, prepare_command},
3 resp::{
4 CommandArgs, MultipleArgsCollection, PrimitiveResponse, SingleArg, SingleArgCollection,
5 ToArgs, cmd, deserialize_vec_of_pairs,
6 },
7};
8use serde::{Deserialize, de::DeserializeOwned};
9
10/// A group of Redis commands related to [`Sorted Sets`](https://redis.io/docs/data-types/sorted-sets/)
11///
12/// # See Also
13/// [Redis Sorted Set Commands](https://redis.io/commands/?group=sorted-set)
14pub trait SortedSetCommands<'a> {
15 /// Adds all the specified members with the specified scores
16 /// to the sorted set stored at key.
17 ///
18 /// # Return
19 /// * When used without optional arguments, the number of elements added to the sorted set (excluding score updates).
20 /// * If the `change` option is specified, the number of elements that were changed (added or updated).
21 ///
22 /// # See Also
23 /// [<https://redis.io/commands/zadd/>](https://redis.io/commands/zadd/)
24 #[must_use]
25 fn zadd<K, M, I>(
26 self,
27 key: K,
28 items: I,
29 options: ZAddOptions,
30 ) -> PreparedCommand<'a, Self, usize>
31 where
32 Self: Sized,
33 K: SingleArg,
34 M: SingleArg,
35 I: MultipleArgsCollection<(f64, M)>,
36 {
37 prepare_command(self, cmd("ZADD").arg(key).arg(options).arg(items))
38 }
39
40 /// In this mode ZADD acts like ZINCRBY.
41 /// Only one score-element pair can be specified in this mode.
42 ///
43 /// # Return
44 /// The new score of member (a double precision floating point number),
45 /// or nil if the operation was aborted (when called with either the XX or the NX option).
46 ///
47 /// # See Also
48 /// [<https://redis.io/commands/zadd/>](https://redis.io/commands/zadd/)
49 #[must_use]
50 fn zadd_incr<K, M>(
51 self,
52 key: K,
53 condition: ZAddCondition,
54 comparison: ZAddComparison,
55 change: bool,
56 score: f64,
57 member: M,
58 ) -> PreparedCommand<'a, Self, Option<f64>>
59 where
60 Self: Sized,
61 K: SingleArg,
62 M: SingleArg,
63 {
64 prepare_command(
65 self,
66 cmd("ZADD")
67 .arg(key)
68 .arg(condition)
69 .arg(comparison)
70 .arg_if(change, "CH")
71 .arg(score)
72 .arg(member),
73 )
74 }
75
76 /// Returns the sorted set cardinality (number of elements)
77 /// of the sorted set stored at key.
78 ///
79 /// # Return
80 /// The cardinality (number of elements) of the sorted set, or 0 if key does not exist.
81 ///
82 /// # See Also
83 /// [<https://redis.io/commands/zcard/>](https://redis.io/commands/zcard/)
84 #[must_use]
85 fn zcard<K>(self, key: K) -> PreparedCommand<'a, Self, usize>
86 where
87 Self: Sized,
88 K: SingleArg,
89 {
90 prepare_command(self, cmd("ZCARD").arg(key))
91 }
92
93 /// Returns the number of elements in the sorted set at key with a score between min and max.
94 ///
95 /// # Return
96 /// The number of elements in the specified score range.
97 ///
98 /// # See Also
99 /// [<https://redis.io/commands/zcount/>](https://redis.io/commands/zcount/)
100 #[must_use]
101 fn zcount<K, M1, M2>(self, key: K, min: M1, max: M2) -> PreparedCommand<'a, Self, usize>
102 where
103 Self: Sized,
104 K: SingleArg,
105 M1: SingleArg,
106 M2: SingleArg,
107 {
108 prepare_command(self, cmd("ZCOUNT").arg(key).arg(min).arg(max))
109 }
110
111 /// This command is similar to [zdiffstore](SortedSetCommands::zdiffstore), but instead of storing the resulting sorted set,
112 /// it is returned to the client.
113 ///
114 /// # Return
115 /// The result of the difference
116 ///
117 /// # See Also
118 /// [<https://redis.io/commands/zdiff/>](https://redis.io/commands/zdiff/)
119 #[must_use]
120 fn zdiff<K, C, E>(self, keys: C) -> PreparedCommand<'a, Self, Vec<E>>
121 where
122 Self: Sized,
123 K: SingleArg,
124 C: SingleArgCollection<K>,
125 E: PrimitiveResponse + DeserializeOwned,
126 {
127 prepare_command(self, cmd("ZDIFF").arg(keys.num_args()).arg(keys))
128 }
129
130 /// This command is similar to [zdiffstore](SortedSetCommands::zdiffstore), but instead of storing the resulting sorted set,
131 /// it is returned to the client.
132 ///
133 /// # Return
134 /// The result of the difference with their scores
135 ///
136 /// # See Also
137 /// [<https://redis.io/commands/zdiff/>](https://redis.io/commands/zdiff/)
138 #[must_use]
139 fn zdiff_with_scores<K, C, E>(self, keys: C) -> PreparedCommand<'a, Self, Vec<(E, f64)>>
140 where
141 Self: Sized,
142 K: SingleArg,
143 C: SingleArgCollection<K>,
144 E: PrimitiveResponse + DeserializeOwned,
145 {
146 prepare_command(
147 self,
148 cmd("ZDIFF")
149 .arg(keys.num_args())
150 .arg(keys)
151 .arg("WITHSCORES"),
152 )
153 }
154
155 /// Computes the difference between the first and all successive
156 /// input sorted sets and stores the result in destination.
157 ///
158 /// # Return
159 /// The number of elements in the resulting sorted set at destination.
160 ///
161 /// # See Also
162 /// [<https://redis.io/commands/zdiffstore/>](https://redis.io/commands/zdiffstore/)
163 #[must_use]
164 fn zdiffstore<D, K, C>(self, destination: D, keys: C) -> PreparedCommand<'a, Self, usize>
165 where
166 Self: Sized,
167 D: SingleArg,
168 K: SingleArg,
169 C: SingleArgCollection<K>,
170 {
171 prepare_command(
172 self,
173 cmd("ZDIFFSTORE")
174 .arg(destination)
175 .arg(keys.num_args())
176 .arg(keys),
177 )
178 }
179
180 /// Increments the score of member in the sorted set stored at key by increment.
181 ///
182 /// # Return
183 /// the new score of member
184 ///
185 /// # See Also
186 /// [<https://redis.io/commands/zincrby/>](https://redis.io/commands/zincrby/)
187 #[must_use]
188 fn zincrby<K, M>(self, key: K, increment: f64, member: M) -> PreparedCommand<'a, Self, f64>
189 where
190 Self: Sized,
191 K: SingleArg,
192 M: SingleArg,
193 {
194 prepare_command(self, cmd("ZINCRBY").arg(key).arg(increment).arg(member))
195 }
196
197 /// This command is similar to [zinterstore](SortedSetCommands::zinterstore),
198 /// but instead of storing the resulting sorted set, it is returned to the client.
199 ///
200 /// # Return
201 /// The result of the intersection as an array of members
202 ///
203 /// # See Also
204 /// [<https://redis.io/commands/zinter/>](https://redis.io/commands/zinter/)
205 #[must_use]
206 fn zinter<K, C, W, E>(
207 self,
208 keys: C,
209 weights: Option<W>,
210 aggregate: ZAggregate,
211 ) -> PreparedCommand<'a, Self, Vec<E>>
212 where
213 Self: Sized,
214 K: SingleArg,
215 C: SingleArgCollection<K>,
216 W: SingleArgCollection<f64>,
217 E: PrimitiveResponse + DeserializeOwned,
218 {
219 prepare_command(
220 self,
221 cmd("ZINTER")
222 .arg(keys.num_args())
223 .arg(keys)
224 .arg(weights.map(|w| ("WEIGHTS", w)))
225 .arg(aggregate),
226 )
227 }
228
229 /// This command is similar to [zinterstore](SortedSetCommands::zinterstore),
230 /// but instead of storing the resulting sorted set, it is returned to the client.
231 ///
232 /// # Return
233 /// The result of the intersection as an array of members with their scores
234 ///
235 /// # See Also
236 /// [<https://redis.io/commands/zinter/>](https://redis.io/commands/zinter/)
237 #[must_use]
238 fn zinter_with_scores<K, C, W, E>(
239 self,
240 keys: C,
241 weights: Option<W>,
242 aggregate: ZAggregate,
243 ) -> PreparedCommand<'a, Self, Vec<(E, f64)>>
244 where
245 Self: Sized,
246 K: SingleArg,
247 C: SingleArgCollection<K>,
248 W: SingleArgCollection<f64>,
249 E: PrimitiveResponse + DeserializeOwned,
250 {
251 prepare_command(
252 self,
253 cmd("ZINTER")
254 .arg(keys.num_args())
255 .arg(keys)
256 .arg(weights.map(|w| ("WEIGHTS", w)))
257 .arg(aggregate)
258 .arg("WITHSCORES"),
259 )
260 }
261
262 /// This command is similar to [zinter](SortedSetCommands::zinter),
263 /// but instead of returning the result set, it returns just the cardinality of the result.
264 ///
265 //// limit: if the intersection cardinality reaches limit partway through the computation,
266 /// the algorithm will exit and yield limit as the cardinality. 0 means unlimited
267 ///
268 /// # See Also
269 /// [<https://redis.io/commands/zintercard/>](https://redis.io/commands/zintercard/)
270 #[must_use]
271 fn zintercard<K, C>(self, keys: C, limit: usize) -> PreparedCommand<'a, Self, usize>
272 where
273 Self: Sized,
274 K: SingleArg,
275 C: SingleArgCollection<K>,
276 {
277 prepare_command(
278 self,
279 cmd("ZINTERCARD")
280 .arg(keys.num_args())
281 .arg(keys)
282 .arg("LIMIT")
283 .arg(limit),
284 )
285 }
286
287 /// Computes the intersection of numkeys sorted sets given by the specified keys,
288 /// and stores the result in destination.
289 ///
290 /// # Return
291 /// The number of elements in the resulting sorted set at destination.
292 ///
293 /// # See Also
294 /// [<https://redis.io/commands/zinterstore/>](https://redis.io/commands/zinterstore/)
295 #[must_use]
296 fn zinterstore<D, K, C, W>(
297 self,
298 destination: D,
299 keys: C,
300 weights: Option<W>,
301 aggregate: ZAggregate,
302 ) -> PreparedCommand<'a, Self, usize>
303 where
304 Self: Sized,
305 D: SingleArg,
306 K: SingleArg,
307 C: SingleArgCollection<K>,
308 W: SingleArgCollection<f64>,
309 {
310 prepare_command(
311 self,
312 cmd("ZINTERSTORE")
313 .arg(destination)
314 .arg(keys.num_args())
315 .arg(keys)
316 .arg(weights.map(|w| ("WEIGHTS", w)))
317 .arg(aggregate),
318 )
319 }
320
321 /// When all the elements in a sorted set are inserted with the same score,
322 /// in order to force lexicographical ordering, this command returns the number
323 /// of elements in the sorted set at key with a value between min and max.
324 ///
325 /// # Return
326 /// the number of elements in the specified score range.
327 ///
328 /// # See Also
329 /// [<https://redis.io/commands/zlexcount/>](https://redis.io/commands/zlexcount/)
330 #[must_use]
331 fn zlexcount<K, M1, M2>(self, key: K, min: M1, max: M2) -> PreparedCommand<'a, Self, usize>
332 where
333 Self: Sized,
334 K: SingleArg,
335 M1: SingleArg,
336 M2: SingleArg,
337 {
338 prepare_command(self, cmd("ZLEXCOUNT").arg(key).arg(min).arg(max))
339 }
340
341 /// Pops one or more elements, that are member-score pairs,
342 /// from the first non-empty sorted set in the provided list of key names.
343 ///
344 /// # Return
345 /// * None if no element could be popped
346 /// * A tuple made up of
347 /// * The name of the key from which elements were popped
348 /// * An array of tuples with all the popped members and their scores
349 ///
350 /// # See Also
351 /// [<https://redis.io/commands/zmpop/>](https://redis.io/commands/zmpop/)
352 #[must_use]
353 fn zmpop<K, C, E>(
354 self,
355 keys: C,
356 where_: ZWhere,
357 count: usize,
358 ) -> PreparedCommand<'a, Self, Option<ZMPopResult<E>>>
359 where
360 Self: Sized,
361 K: SingleArg,
362 C: SingleArgCollection<K>,
363 E: PrimitiveResponse + DeserializeOwned,
364 {
365 prepare_command(
366 self,
367 cmd("ZMPOP")
368 .arg(keys.num_args())
369 .arg(keys)
370 .arg(where_)
371 .arg("COUNT")
372 .arg(count),
373 )
374 }
375
376 /// Returns the scores associated with the specified members in the sorted set stored at key.
377 ///
378 /// For every member that does not exist in the sorted set, a nil value is returned.
379 ///
380 /// # Return
381 /// The list of scores or nil associated with the specified member value
382 ///
383 /// # See Also
384 /// [<https://redis.io/commands/zmscore/>](https://redis.io/commands/zmscore/)
385 #[must_use]
386 fn zmscore<K, M, C>(self, key: K, members: C) -> PreparedCommand<'a, Self, Vec<Option<f64>>>
387 where
388 Self: Sized,
389 K: SingleArg,
390 M: SingleArg,
391 C: SingleArgCollection<M>,
392 {
393 prepare_command(self, cmd("ZMSCORE").arg(key).arg(members))
394 }
395
396 /// Removes and returns up to count members with the highest scores in the sorted set stored at key.
397 ///
398 /// # Return
399 /// The list of popped elements and scores.
400 ///
401 /// # See Also
402 /// [<https://redis.io/commands/zpopmax/>](https://redis.io/commands/zpopmax/)
403 #[must_use]
404 fn zpopmax<K, M>(self, key: K, count: usize) -> PreparedCommand<'a, Self, Vec<(M, f64)>>
405 where
406 Self: Sized,
407 K: SingleArg,
408 M: PrimitiveResponse + DeserializeOwned,
409 {
410 prepare_command(self, cmd("ZPOPMAX").arg(key).arg(count))
411 }
412
413 /// Removes and returns up to count members with the lowest scores in the sorted set stored at key.
414 ///
415 /// # Return
416 /// The list of popped elements and scores.
417 ///
418 /// # See Also
419 /// [<https://redis.io/commands/zpopmin/>](https://redis.io/commands/zpopmin/)
420 #[must_use]
421 fn zpopmin<K, M>(self, key: K, count: usize) -> PreparedCommand<'a, Self, Vec<(M, f64)>>
422 where
423 Self: Sized,
424 K: SingleArg,
425 M: PrimitiveResponse + DeserializeOwned,
426 {
427 prepare_command(self, cmd("ZPOPMIN").arg(key).arg(count))
428 }
429
430 /// Return a random element from the sorted set value stored at key.
431 ///
432 /// # Return
433 /// The randomly selected element, or nil when key does not exist.
434 ///
435 /// # See Also
436 /// [<https://redis.io/commands/zrandmember/>](https://redis.io/commands/zrandmember/)
437 #[must_use]
438 fn zrandmember<K, E>(self, key: K) -> PreparedCommand<'a, Self, E>
439 where
440 Self: Sized,
441 K: SingleArg,
442 E: PrimitiveResponse,
443 {
444 prepare_command(self, cmd("ZRANDMEMBER").arg(key))
445 }
446
447 /// Return random elements from the sorted set value stored at key.
448 ///
449 /// # Return
450 /// * If the provided count argument is positive, return an array of distinct elements.
451 /// The array's length is either count or the sorted set's cardinality (ZCARD), whichever is lower.
452 /// * If called with a negative count, the behavior changes and the command is allowed
453 /// to return the same element multiple times. In this case, the number of returned elements
454 /// is the absolute value of the specified count.
455 ///
456 /// # See Also
457 /// [<https://redis.io/commands/zrandmember/>](https://redis.io/commands/zrandmember/)
458 #[must_use]
459 fn zrandmembers<K, E>(self, key: K, count: isize) -> PreparedCommand<'a, Self, Vec<E>>
460 where
461 Self: Sized,
462 K: SingleArg,
463 E: PrimitiveResponse + DeserializeOwned,
464 {
465 prepare_command(self, cmd("ZRANDMEMBER").arg(key).arg(count))
466 }
467
468 /// Return random elements with their scores from the sorted set value stored at key.
469 ///
470 /// # Return
471 /// * If the provided count argument is positive, return an array of distinct elements with their scores.
472 /// The array's length is either count or the sorted set's cardinality (ZCARD), whichever is lower.
473 /// * If called with a negative count, the behavior changes and the command is allowed
474 /// to return the same element multiple times. In this case, the number of returned elements
475 /// is the absolute value of the specified count.
476 ///
477 /// # See Also
478 /// [<https://redis.io/commands/zrandmember/>](https://redis.io/commands/zrandmember/)
479 #[must_use]
480 fn zrandmembers_with_scores<K, E>(
481 self,
482 key: K,
483 count: isize,
484 ) -> PreparedCommand<'a, Self, Vec<E>>
485 where
486 Self: Sized,
487 K: SingleArg,
488 E: DeserializeOwned,
489 {
490 prepare_command(
491 self,
492 cmd("ZRANDMEMBER").arg(key).arg(count).arg("WITHSCORES"),
493 )
494 }
495
496 /// Returns the specified range of elements in the sorted set stored at `key`.
497 ///
498 /// # Return
499 /// A collection of elements in the specified range
500 ///
501 /// # See Also
502 /// [<https://redis.io/commands/zrange/>](https://redis.io/commands/zrange/)
503 #[must_use]
504 fn zrange<K, S, E>(
505 self,
506 key: K,
507 start: S,
508 stop: S,
509 options: ZRangeOptions,
510 ) -> PreparedCommand<'a, Self, Vec<E>>
511 where
512 Self: Sized,
513 K: SingleArg,
514 S: SingleArg,
515 E: PrimitiveResponse + DeserializeOwned,
516 {
517 prepare_command(
518 self,
519 cmd("ZRANGE").arg(key).arg(start).arg(stop).arg(options),
520 )
521 }
522
523 /// Returns the specified range of elements in the sorted set stored at `key`.
524 ///
525 /// # Return
526 /// A collection of elements and their scores in the specified range
527 ///
528 /// # See Also
529 /// [<https://redis.io/commands/zrange/>](https://redis.io/commands/zrange/)
530 #[must_use]
531 fn zrange_with_scores<K, S, E>(
532 self,
533 key: K,
534 start: S,
535 stop: S,
536 options: ZRangeOptions,
537 ) -> PreparedCommand<'a, Self, Vec<(E, f64)>>
538 where
539 Self: Sized,
540 K: SingleArg,
541 S: SingleArg,
542 E: PrimitiveResponse + DeserializeOwned,
543 {
544 prepare_command(
545 self,
546 cmd("ZRANGE")
547 .arg(key)
548 .arg(start)
549 .arg(stop)
550 .arg(options)
551 .arg("WITHSCORES"),
552 )
553 }
554
555 /// This command is like [zrange](SortedSetCommands::zrange),
556 /// but stores the result in the `dst` destination key.
557 ///
558 /// # Return
559 /// The number of elements in the resulting sorted set.
560 ///
561 /// # See Also
562 /// [<https://redis.io/commands/zrangestore/>](https://redis.io/commands/zrangestore/)
563 #[must_use]
564 fn zrangestore<D, S, SS>(
565 self,
566 dst: D,
567 src: S,
568 start: SS,
569 stop: SS,
570 options: ZRangeOptions,
571 ) -> PreparedCommand<'a, Self, usize>
572 where
573 Self: Sized,
574 D: SingleArg,
575 S: SingleArg,
576 SS: SingleArg,
577 {
578 prepare_command(
579 self,
580 cmd("ZRANGESTORE")
581 .arg(dst)
582 .arg(src)
583 .arg(start)
584 .arg(stop)
585 .arg(options),
586 )
587 }
588
589 /// Returns the rank of member in the sorted set stored at key,
590 /// with the scores ordered from low to high.
591 ///
592 /// # Return
593 /// * If member exists in the sorted set, the rank of member.
594 /// * If member does not exist in the sorted set or key does not exist, None.
595 ///
596 /// # See Also
597 /// [<https://redis.io/commands/zrank/>](https://redis.io/commands/zrank/)
598 #[must_use]
599 fn zrank<K, M>(self, key: K, member: M) -> PreparedCommand<'a, Self, Option<usize>>
600 where
601 Self: Sized,
602 K: SingleArg,
603 M: SingleArg,
604 {
605 prepare_command(self, cmd("ZRANK").arg(key).arg(member))
606 }
607
608 /// Returns the rank of member in the sorted set stored at key,
609 /// with the scores ordered from low to high.
610 ///
611 /// # Return
612 /// * If member exists in the sorted set, the rank of member and its score
613 /// * If member does not exist in the sorted set or key does not exist, None.
614 ///
615 /// # See Also
616 /// [<https://redis.io/commands/zrank/>](https://redis.io/commands/zrank/)
617 #[must_use]
618 fn zrank_with_score<K, M>(
619 self,
620 key: K,
621 member: M,
622 ) -> PreparedCommand<'a, Self, Option<(usize, f64)>>
623 where
624 Self: Sized,
625 K: SingleArg,
626 M: SingleArg,
627 {
628 prepare_command(self, cmd("ZRANK").arg(key).arg(member).arg("WITHSCORE"))
629 }
630
631 /// Removes the specified members from the sorted set stored at key.
632 ///
633 /// # Return
634 /// The number of members removed from the sorted set, not including non existing members.
635 ///
636 /// # See Also
637 /// [<https://redis.io/commands/zrem/>](https://redis.io/commands/zrem/)
638 #[must_use]
639 fn zrem<K, M, C>(self, key: K, members: C) -> PreparedCommand<'a, Self, usize>
640 where
641 Self: Sized,
642 K: SingleArg,
643 M: SingleArg,
644 C: SingleArgCollection<M>,
645 {
646 prepare_command(self, cmd("ZREM").arg(key).arg(members))
647 }
648
649 /// When all the elements in a sorted set are inserted with the same score,
650 /// in order to force lexicographical ordering,
651 /// this command removes all elements in the sorted set stored at key
652 /// between the lexicographical range specified by min and max.
653 ///
654 /// # Return
655 /// the number of elements removed.
656 ///
657 /// # See Also
658 /// [<https://redis.io/commands/zremrangebylex/>](https://redis.io/commands/zremrangebylex/)
659 #[must_use]
660 fn zremrangebylex<K, S>(self, key: K, start: S, stop: S) -> PreparedCommand<'a, Self, usize>
661 where
662 Self: Sized,
663 K: SingleArg,
664 S: SingleArg,
665 {
666 prepare_command(self, cmd("ZREMRANGEBYLEX").arg(key).arg(start).arg(stop))
667 }
668
669 /// Removes all elements in the sorted set stored at key with rank between start and stop.
670 ///
671 /// # Return
672 /// the number of elements removed.
673 ///
674 /// # See Also
675 /// [<https://redis.io/commands/zremrangebyrank/>](https://redis.io/commands/zremrangebyrank/)
676 #[must_use]
677 fn zremrangebyrank<K>(
678 self,
679 key: K,
680 start: isize,
681 stop: isize,
682 ) -> PreparedCommand<'a, Self, usize>
683 where
684 Self: Sized,
685 K: SingleArg,
686 {
687 prepare_command(self, cmd("ZREMRANGEBYRANK").arg(key).arg(start).arg(stop))
688 }
689
690 /// Removes all elements in the sorted set stored at key with a score between min and max (inclusive).
691 ///
692 /// # Return
693 /// the number of elements removed.
694 ///
695 /// # See Also
696 /// [<https://redis.io/commands/zremrangebyscore/>](https://redis.io/commands/zremrangebyscore/)
697 #[must_use]
698 fn zremrangebyscore<K, S>(self, key: K, start: S, stop: S) -> PreparedCommand<'a, Self, usize>
699 where
700 Self: Sized,
701 K: SingleArg,
702 S: SingleArg,
703 {
704 prepare_command(self, cmd("ZREMRANGEBYSCORE").arg(key).arg(start).arg(stop))
705 }
706
707 /// Returns the rank of member in the sorted set stored at key, with the scores ordered from high to low.
708 ///
709 /// # Return
710 /// * If member exists in the sorted set, the rank of member.
711 /// * If member does not exist in the sorted set or key does not exist, None.
712 ///
713 /// # See Also
714 /// [<https://redis.io/commands/zrevrank/>](https://redis.io/commands/zrevrank/)
715 #[must_use]
716 fn zrevrank<K, M>(self, key: K, member: M) -> PreparedCommand<'a, Self, Option<usize>>
717 where
718 Self: Sized,
719 K: SingleArg,
720 M: SingleArg,
721 {
722 prepare_command(self, cmd("ZREVRANK").arg(key).arg(member))
723 }
724
725 /// Returns the rank of member in the sorted set stored at key, with the scores ordered from high to low.
726 ///
727 /// # Return
728 /// * If member exists in the sorted set, the rank of member and its score.
729 /// * If member does not exist in the sorted set or key does not exist, None.
730 ///
731 /// # See Also
732 /// [<https://redis.io/commands/zrevrank/>](https://redis.io/commands/zrevrank/)
733 #[must_use]
734 fn zrevrank_with_score<K, M>(
735 self,
736 key: K,
737 member: M,
738 ) -> PreparedCommand<'a, Self, Option<(usize, f64)>>
739 where
740 Self: Sized,
741 K: SingleArg,
742 M: SingleArg,
743 {
744 prepare_command(self, cmd("ZREVRANK").arg(key).arg(member).arg("WITHSCORE"))
745 }
746
747 /// Iterates elements of Sorted Set types and their associated scores.
748 ///
749 /// # Returns
750 /// A tuple where
751 /// * The first value is the cursor as an unsigned 64 bit number
752 /// * The second value is a list of members and their scores in a Vec of Tuples
753 ///
754 /// # See Also
755 /// [<https://redis.io/commands/zscan/>](https://redis.io/commands/zscan/)
756 #[must_use]
757 fn zscan<K, M>(
758 self,
759 key: K,
760 cursor: usize,
761 options: ZScanOptions,
762 ) -> PreparedCommand<'a, Self, ZScanResult<M>>
763 where
764 Self: Sized,
765 K: SingleArg,
766 M: PrimitiveResponse + DeserializeOwned,
767 {
768 prepare_command(self, cmd("ZSCAN").arg(key).arg(cursor).arg(options))
769 }
770
771 /// Returns the score of member in the sorted set at key.
772 ///
773 /// # Return
774 /// The score of `member` or nil if `key`does not exist
775 ///
776 /// # See Also
777 /// [<https://redis.io/commands/zscore/>](https://redis.io/commands/zscore/)
778 #[must_use]
779 fn zscore<K, M>(self, key: K, member: M) -> PreparedCommand<'a, Self, Option<f64>>
780 where
781 Self: Sized,
782 K: SingleArg,
783 M: SingleArg,
784 {
785 prepare_command(self, cmd("ZSCORE").arg(key).arg(member))
786 }
787
788 /// This command is similar to [zunionstore](SortedSetCommands::zunionstore),
789 /// but instead of storing the resulting sorted set, it is returned to the client.
790 ///
791 /// # Return
792 /// The result of the unionsection as an array of members
793 ///
794 /// # See Also
795 /// [<https://redis.io/commands/zunion/>](https://redis.io/commands/zunion/)
796 #[must_use]
797 fn zunion<K, C, W, E>(
798 self,
799 keys: C,
800 weights: Option<W>,
801 aggregate: ZAggregate,
802 ) -> PreparedCommand<'a, Self, Vec<E>>
803 where
804 Self: Sized,
805 K: SingleArg,
806 C: SingleArgCollection<K>,
807 W: SingleArgCollection<f64>,
808 E: PrimitiveResponse + DeserializeOwned,
809 {
810 prepare_command(
811 self,
812 cmd("ZUNION")
813 .arg(keys.num_args())
814 .arg(keys)
815 .arg(weights.map(|w| ("WEIGHTS", w)))
816 .arg(aggregate),
817 )
818 }
819
820 /// This command is similar to [zunionstore](SortedSetCommands::zunionstore),
821 /// but instead of storing the resulting sorted set, it is returned to the client.
822 ///
823 /// # Return
824 /// The result of the unionsection as an array of members with their scores
825 ///
826 /// # See Also
827 /// [<https://redis.io/commands/zunion/>](https://redis.io/commands/zunion/)
828 #[must_use]
829 fn zunion_with_scores<K, C, W, E>(
830 self,
831 keys: C,
832 weights: Option<W>,
833 aggregate: ZAggregate,
834 ) -> PreparedCommand<'a, Self, Vec<(E, f64)>>
835 where
836 Self: Sized,
837 K: SingleArg,
838 C: SingleArgCollection<K>,
839 W: SingleArgCollection<f64>,
840 E: PrimitiveResponse + DeserializeOwned,
841 {
842 prepare_command(
843 self,
844 cmd("ZUNION")
845 .arg(keys.num_args())
846 .arg(keys)
847 .arg(weights.map(|w| ("WEIGHTS", w)))
848 .arg(aggregate)
849 .arg("WITHSCORES"),
850 )
851 }
852
853 /// Computes the unionsection of numkeys sorted sets given by the specified keys,
854 /// and stores the result in destination.
855 ///
856 /// # Return
857 /// The number of elements in the resulting sorted set at destination.
858 ///
859 /// # See Also
860 /// [<https://redis.io/commands/zunionstore/>](https://redis.io/commands/zunionstore/)
861 #[must_use]
862 fn zunionstore<D, K, C, W>(
863 self,
864 destination: D,
865 keys: C,
866 weights: Option<W>,
867 aggregate: ZAggregate,
868 ) -> PreparedCommand<'a, Self, usize>
869 where
870 Self: Sized,
871 D: SingleArg,
872 K: SingleArg,
873 C: SingleArgCollection<K>,
874 W: SingleArgCollection<f64>,
875 {
876 prepare_command(
877 self,
878 cmd("ZUNIONSTORE")
879 .arg(destination)
880 .arg(keys.num_args())
881 .arg(keys)
882 .arg(weights.map(|w| ("WEIGHTS", w)))
883 .arg(aggregate),
884 )
885 }
886}
887
888/// Condition option for the [`zadd`](SortedSetCommands::zadd) command
889#[derive(Default)]
890pub enum ZAddCondition {
891 /// No condition
892 #[default]
893 None,
894 /// Only update elements that already exist. Don't add new elements.
895 NX,
896 /// Only add new elements. Don't update already existing elements.
897 XX,
898}
899
900impl ToArgs for ZAddCondition {
901 fn write_args(&self, args: &mut CommandArgs) {
902 match self {
903 ZAddCondition::None => {}
904 ZAddCondition::NX => {
905 args.arg("NX");
906 }
907 ZAddCondition::XX => {
908 args.arg("XX");
909 }
910 }
911 }
912}
913
914/// Comparison option for the [`zadd`](SortedSetCommands::zadd) command
915#[derive(Default)]
916pub enum ZAddComparison {
917 /// No comparison
918 #[default]
919 None,
920 /// Only update existing elements if the new score is greater than the current score.
921 ///
922 /// This flag doesn't prevent adding new elements.
923 GT,
924 /// Only update existing elements if the new score is less than the current score.
925 ///
926 /// This flag doesn't prevent adding new elements.
927 LT,
928}
929
930impl ToArgs for ZAddComparison {
931 fn write_args(&self, args: &mut CommandArgs) {
932 match self {
933 ZAddComparison::None => {}
934 ZAddComparison::GT => {
935 args.arg("GT");
936 }
937 ZAddComparison::LT => {
938 args.arg("LT");
939 }
940 }
941 }
942}
943
944/// sort by option of the [`zrange`](SortedSetCommands::zrange) command
945#[derive(Default)]
946pub enum ZRangeSortBy {
947 /// No sort by
948 #[default]
949 None,
950 /// When the `ByScore` option is provided, the command behaves like `ZRANGEBYSCORE` and returns
951 /// the range of elements from the sorted set having scores equal or between `start` and `stop`.
952 ByScore,
953 /// When the `ByLex` option is used, the command behaves like `ZRANGEBYLEX` and returns the range
954 /// of elements from the sorted set between the `start` and `stop` lexicographical closed range intervals.
955 ByLex,
956}
957
958impl ToArgs for ZRangeSortBy {
959 fn write_args(&self, args: &mut CommandArgs) {
960 match self {
961 ZRangeSortBy::None => {}
962 ZRangeSortBy::ByScore => {
963 args.arg("BYSCORE");
964 }
965 ZRangeSortBy::ByLex => {
966 args.arg("BYLEX");
967 }
968 }
969 }
970}
971
972/// Option that specify how results of an union or intersection are aggregated
973///
974/// # See Also
975/// [zinter](SortedSetCommands::zinter)
976/// [zinterstore](SortedSetCommands::zinterstore)
977/// [zunion](SortedSetCommands::zunion)
978/// [zunionstore](SortedSetCommands::zunionstore)
979#[derive(Default)]
980pub enum ZAggregate {
981 /// No aggregation
982 #[default]
983 None,
984 /// The score of an element is summed across the inputs where it exists.
985 Sum,
986 /// The minimum score of an element across the inputs where it exists.
987 Min,
988 /// The maximum score of an element across the inputs where it exists.
989 Max,
990}
991
992impl ToArgs for ZAggregate {
993 fn write_args(&self, args: &mut CommandArgs) {
994 match self {
995 ZAggregate::None => {}
996 ZAggregate::Sum => {
997 args.arg("SUM");
998 }
999 ZAggregate::Min => {
1000 args.arg("MIN");
1001 }
1002 ZAggregate::Max => {
1003 args.arg("MAX");
1004 }
1005 }
1006 }
1007}
1008
1009/// Where option of the [`zmpop`](SortedSetCommands::zmpop) command
1010pub enum ZWhere {
1011 /// When the MIN modifier is used, the elements popped are those
1012 /// with the lowest scores from the first non-empty sorted set.
1013 Min,
1014 /// The MAX modifier causes elements with the highest scores to be popped.
1015 Max,
1016}
1017
1018impl ToArgs for ZWhere {
1019 fn write_args(&self, args: &mut CommandArgs) {
1020 match self {
1021 ZWhere::Min => args.arg("MIN"),
1022 ZWhere::Max => args.arg("MAX"),
1023 };
1024 }
1025}
1026
1027/// Options for the [`zadd`](SortedSetCommands::zadd) command.
1028#[derive(Default)]
1029pub struct ZAddOptions {
1030 command_args: CommandArgs,
1031}
1032
1033impl ZAddOptions {
1034 #[must_use]
1035 pub fn condition(mut self, condition: ZAddCondition) -> Self {
1036 Self {
1037 command_args: self.command_args.arg(condition).build(),
1038 }
1039 }
1040
1041 #[must_use]
1042 pub fn comparison(mut self, comparison: ZAddComparison) -> Self {
1043 Self {
1044 command_args: self.command_args.arg(comparison).build(),
1045 }
1046 }
1047
1048 #[must_use]
1049 pub fn change(mut self) -> Self {
1050 Self {
1051 command_args: self.command_args.arg("CH").build(),
1052 }
1053 }
1054}
1055
1056impl ToArgs for ZAddOptions {
1057 fn write_args(&self, args: &mut CommandArgs) {
1058 self.command_args.write_args(args);
1059 }
1060}
1061
1062/// Result for [`zmpop`](SortedSetCommands::zmpop) the command.
1063pub type ZMPopResult<E> = (String, Vec<(E, f64)>);
1064
1065/// Options for the [`zrange`](SortedSetCommands::zrange)
1066/// and [`zrangestore`](SortedSetCommands::zrangestore) commands
1067#[derive(Default)]
1068pub struct ZRangeOptions {
1069 command_args: CommandArgs,
1070}
1071
1072impl ZRangeOptions {
1073 #[must_use]
1074 pub fn sort_by(mut self, sort_by: ZRangeSortBy) -> Self {
1075 Self {
1076 command_args: self.command_args.arg(sort_by).build(),
1077 }
1078 }
1079
1080 #[must_use]
1081 pub fn reverse(mut self) -> Self {
1082 Self {
1083 command_args: self.command_args.arg("REV").build(),
1084 }
1085 }
1086
1087 #[must_use]
1088 pub fn limit(mut self, offset: usize, count: isize) -> Self {
1089 Self {
1090 command_args: self
1091 .command_args
1092 .arg("LIMIT")
1093 .arg(offset)
1094 .arg(count)
1095 .build(),
1096 }
1097 }
1098}
1099
1100impl ToArgs for ZRangeOptions {
1101 fn write_args(&self, args: &mut CommandArgs) {
1102 args.arg(&self.command_args);
1103 }
1104}
1105
1106/// Options for the [`zscan`](SortedSetCommands::zscan) command
1107#[derive(Default)]
1108pub struct ZScanOptions {
1109 command_args: CommandArgs,
1110}
1111
1112impl ZScanOptions {
1113 #[must_use]
1114 pub fn match_pattern<P: SingleArg>(mut self, match_pattern: P) -> Self {
1115 Self {
1116 command_args: self.command_args.arg("MATCH").arg(match_pattern).build(),
1117 }
1118 }
1119
1120 #[must_use]
1121 pub fn count(mut self, count: usize) -> Self {
1122 Self {
1123 command_args: self.command_args.arg("COUNT").arg(count).build(),
1124 }
1125 }
1126}
1127
1128impl ToArgs for ZScanOptions {
1129 fn write_args(&self, args: &mut CommandArgs) {
1130 args.arg(&self.command_args);
1131 }
1132}
1133
1134/// Result for the [`zscan`](SortedSetCommands::zscan) command.
1135#[derive(Debug, Deserialize)]
1136pub struct ZScanResult<M>
1137where
1138 M: PrimitiveResponse + DeserializeOwned,
1139{
1140 pub cursor: u64,
1141 #[serde(deserialize_with = "deserialize_vec_of_pairs")]
1142 pub elements: Vec<(M, f64)>,
1143}