rustis/commands/sorted_set_commands.rs
1use crate::{
2 client::{prepare_command, PreparedCommand},
3 resp::{
4 cmd, deserialize_vec_of_pairs, CommandArgs, MultipleArgsCollection, PrimitiveResponse,
5 SingleArg, SingleArgCollection, ToArgs,
6 },
7};
8use serde::{de::DeserializeOwned, Deserialize};
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 /// Removes the specified members from the sorted set stored at key.
609 ///
610 /// # Return
611 /// The number of members removed from the sorted set, not including non existing members.
612 ///
613 /// # See Also
614 /// [<https://redis.io/commands/zrem/>](https://redis.io/commands/zrem/)
615 #[must_use]
616 fn zrem<K, M, C>(self, key: K, members: C) -> PreparedCommand<'a, Self, usize>
617 where
618 Self: Sized,
619 K: SingleArg,
620 M: SingleArg,
621 C: SingleArgCollection<M>,
622 {
623 prepare_command(self, cmd("ZREM").arg(key).arg(members))
624 }
625
626 /// When all the elements in a sorted set are inserted with the same score,
627 /// in order to force lexicographical ordering,
628 /// this command removes all elements in the sorted set stored at key
629 /// between the lexicographical range specified by min and max.
630 ///
631 /// # Return
632 /// the number of elements removed.
633 ///
634 /// # See Also
635 /// [<https://redis.io/commands/zremrangebylex/>](https://redis.io/commands/zremrangebylex/)
636 #[must_use]
637 fn zremrangebylex<K, S>(self, key: K, start: S, stop: S) -> PreparedCommand<'a, Self, usize>
638 where
639 Self: Sized,
640 K: SingleArg,
641 S: SingleArg,
642 {
643 prepare_command(self, cmd("ZREMRANGEBYLEX").arg(key).arg(start).arg(stop))
644 }
645
646 /// Removes all elements in the sorted set stored at key with rank between start and stop.
647 ///
648 /// # Return
649 /// the number of elements removed.
650 ///
651 /// # See Also
652 /// [<https://redis.io/commands/zremrangebyrank/>](https://redis.io/commands/zremrangebyrank/)
653 #[must_use]
654 fn zremrangebyrank<K>(
655 self,
656 key: K,
657 start: isize,
658 stop: isize,
659 ) -> PreparedCommand<'a, Self, usize>
660 where
661 Self: Sized,
662 K: SingleArg,
663 {
664 prepare_command(self, cmd("ZREMRANGEBYRANK").arg(key).arg(start).arg(stop))
665 }
666
667 /// Removes all elements in the sorted set stored at key with a score between min and max (inclusive).
668 ///
669 /// # Return
670 /// the number of elements removed.
671 ///
672 /// # See Also
673 /// [<https://redis.io/commands/zremrangebyscore/>](https://redis.io/commands/zremrangebyscore/)
674 #[must_use]
675 fn zremrangebyscore<K, S>(self, key: K, start: S, stop: S) -> PreparedCommand<'a, Self, usize>
676 where
677 Self: Sized,
678 K: SingleArg,
679 S: SingleArg,
680 {
681 prepare_command(self, cmd("ZREMRANGEBYSCORE").arg(key).arg(start).arg(stop))
682 }
683
684 /// Returns the rank of member in the sorted set stored at key, with the scores ordered from high to low.
685 ///
686 /// # Return
687 /// * If member exists in the sorted set, the rank of member.
688 /// * If member does not exist in the sorted set or key does not exist, None.
689 ///
690 /// # See Also
691 /// [<https://redis.io/commands/zrevrank/>](https://redis.io/commands/zrevrank/)
692 #[must_use]
693 fn zrevrank<K, M>(self, key: K, member: M) -> PreparedCommand<'a, Self, Option<usize>>
694 where
695 Self: Sized,
696 K: SingleArg,
697 M: SingleArg,
698 {
699 prepare_command(self, cmd("ZREVRANK").arg(key).arg(member))
700 }
701
702 /// Iterates elements of Sorted Set types and their associated scores.
703 ///
704 /// # Returns
705 /// A tuple where
706 /// * The first value is the cursor as an unsigned 64 bit number
707 /// * The second value is a list of members and their scores in a Vec of Tuples
708 ///
709 /// # See Also
710 /// [<https://redis.io/commands/zscan/>](https://redis.io/commands/zscan/)
711 #[must_use]
712 fn zscan<K, M>(
713 self,
714 key: K,
715 cursor: usize,
716 options: ZScanOptions,
717 ) -> PreparedCommand<'a, Self, ZScanResult<M>>
718 where
719 Self: Sized,
720 K: SingleArg,
721 M: PrimitiveResponse + DeserializeOwned,
722 {
723 prepare_command(self, cmd("ZSCAN").arg(key).arg(cursor).arg(options))
724 }
725
726 /// Returns the score of member in the sorted set at key.
727 ///
728 /// # Return
729 /// The score of `member` or nil if `key`does not exist
730 ///
731 /// # See Also
732 /// [<https://redis.io/commands/zscore/>](https://redis.io/commands/zscore/)
733 #[must_use]
734 fn zscore<K, M>(self, key: K, member: M) -> PreparedCommand<'a, Self, Option<f64>>
735 where
736 Self: Sized,
737 K: SingleArg,
738 M: SingleArg,
739 {
740 prepare_command(self, cmd("ZSCORE").arg(key).arg(member))
741 }
742
743 /// This command is similar to [zunionstore](SortedSetCommands::zunionstore),
744 /// but instead of storing the resulting sorted set, it is returned to the client.
745 ///
746 /// # Return
747 /// The result of the unionsection as an array of members
748 ///
749 /// # See Also
750 /// [<https://redis.io/commands/zunion/>](https://redis.io/commands/zunion/)
751 #[must_use]
752 fn zunion<K, C, W, E>(
753 self,
754 keys: C,
755 weights: Option<W>,
756 aggregate: ZAggregate,
757 ) -> PreparedCommand<'a, Self, Vec<E>>
758 where
759 Self: Sized,
760 K: SingleArg,
761 C: SingleArgCollection<K>,
762 W: SingleArgCollection<f64>,
763 E: PrimitiveResponse + DeserializeOwned,
764 {
765 prepare_command(
766 self,
767 cmd("ZUNION")
768 .arg(keys.num_args())
769 .arg(keys)
770 .arg(weights.map(|w| ("WEIGHTS", w)))
771 .arg(aggregate),
772 )
773 }
774
775 /// This command is similar to [zunionstore](SortedSetCommands::zunionstore),
776 /// but instead of storing the resulting sorted set, it is returned to the client.
777 ///
778 /// # Return
779 /// The result of the unionsection as an array of members with their scores
780 ///
781 /// # See Also
782 /// [<https://redis.io/commands/zunion/>](https://redis.io/commands/zunion/)
783 #[must_use]
784 fn zunion_with_scores<K, C, W, E>(
785 self,
786 keys: C,
787 weights: Option<W>,
788 aggregate: ZAggregate,
789 ) -> PreparedCommand<'a, Self, Vec<(E, f64)>>
790 where
791 Self: Sized,
792 K: SingleArg,
793 C: SingleArgCollection<K>,
794 W: SingleArgCollection<f64>,
795 E: PrimitiveResponse + DeserializeOwned,
796 {
797 prepare_command(
798 self,
799 cmd("ZUNION")
800 .arg(keys.num_args())
801 .arg(keys)
802 .arg(weights.map(|w| ("WEIGHTS", w)))
803 .arg(aggregate)
804 .arg("WITHSCORES"),
805 )
806 }
807
808 /// Computes the unionsection of numkeys sorted sets given by the specified keys,
809 /// and stores the result in destination.
810 ///
811 /// # Return
812 /// The number of elements in the resulting sorted set at destination.
813 ///
814 /// # See Also
815 /// [<https://redis.io/commands/zunionstore/>](https://redis.io/commands/zunionstore/)
816 #[must_use]
817 fn zunionstore<D, K, C, W>(
818 self,
819 destination: D,
820 keys: C,
821 weights: Option<W>,
822 aggregate: ZAggregate,
823 ) -> PreparedCommand<'a, Self, usize>
824 where
825 Self: Sized,
826 D: SingleArg,
827 K: SingleArg,
828 C: SingleArgCollection<K>,
829 W: SingleArgCollection<f64>,
830 {
831 prepare_command(
832 self,
833 cmd("ZUNIONSTORE")
834 .arg(destination)
835 .arg(keys.num_args())
836 .arg(keys)
837 .arg(weights.map(|w| ("WEIGHTS", w)))
838 .arg(aggregate),
839 )
840 }
841}
842
843/// Condition option for the [`zadd`](SortedSetCommands::zadd) command
844#[derive(Default)]
845pub enum ZAddCondition {
846 /// No condition
847 #[default]
848 None,
849 /// Only update elements that already exist. Don't add new elements.
850 NX,
851 /// Only add new elements. Don't update already existing elements.
852 XX,
853}
854
855impl ToArgs for ZAddCondition {
856 fn write_args(&self, args: &mut CommandArgs) {
857 match self {
858 ZAddCondition::None => {}
859 ZAddCondition::NX => {
860 args.arg("NX");
861 }
862 ZAddCondition::XX => {
863 args.arg("XX");
864 }
865 }
866 }
867}
868
869/// Comparison option for the [`zadd`](SortedSetCommands::zadd) command
870#[derive(Default)]
871pub enum ZAddComparison {
872 /// No comparison
873 #[default]
874 None,
875 /// Only update existing elements if the new score is greater than the current score.
876 ///
877 /// This flag doesn't prevent adding new elements.
878 GT,
879 /// Only update existing elements if the new score is less than the current score.
880 ///
881 /// This flag doesn't prevent adding new elements.
882 LT,
883}
884
885impl ToArgs for ZAddComparison {
886 fn write_args(&self, args: &mut CommandArgs) {
887 match self {
888 ZAddComparison::None => {}
889 ZAddComparison::GT => {
890 args.arg("GT");
891 }
892 ZAddComparison::LT => {
893 args.arg("LT");
894 }
895 }
896 }
897}
898
899/// sort by option of the [`zrange`](SortedSetCommands::zrange) command
900#[derive(Default)]
901pub enum ZRangeSortBy {
902 /// No sort by
903 #[default]
904 None,
905 /// When the `ByScore` option is provided, the command behaves like `ZRANGEBYSCORE` and returns
906 /// the range of elements from the sorted set having scores equal or between `start` and `stop`.
907 ByScore,
908 /// When the `ByLex` option is used, the command behaves like `ZRANGEBYLEX` and returns the range
909 /// of elements from the sorted set between the `start` and `stop` lexicographical closed range intervals.
910 ByLex,
911}
912
913impl ToArgs for ZRangeSortBy {
914 fn write_args(&self, args: &mut CommandArgs) {
915 match self {
916 ZRangeSortBy::None => {}
917 ZRangeSortBy::ByScore => {
918 args.arg("BYSCORE");
919 }
920 ZRangeSortBy::ByLex => {
921 args.arg("BYLEX");
922 }
923 }
924 }
925}
926
927/// Option that specify how results of an union or intersection are aggregated
928///
929/// # See Also
930/// [zinter](SortedSetCommands::zinter)
931/// [zinterstore](SortedSetCommands::zinterstore)
932/// [zunion](SortedSetCommands::zunion)
933/// [zunionstore](SortedSetCommands::zunionstore)
934#[derive(Default)]
935pub enum ZAggregate {
936 /// No aggregation
937 #[default]
938 None,
939 /// The score of an element is summed across the inputs where it exists.
940 Sum,
941 /// The minimum score of an element across the inputs where it exists.
942 Min,
943 /// The maximum score of an element across the inputs where it exists.
944 Max,
945}
946
947impl ToArgs for ZAggregate {
948 fn write_args(&self, args: &mut CommandArgs) {
949 match self {
950 ZAggregate::None => {}
951 ZAggregate::Sum => {
952 args.arg("SUM");
953 }
954 ZAggregate::Min => {
955 args.arg("MIN");
956 }
957 ZAggregate::Max => {
958 args.arg("MAX");
959 }
960 }
961 }
962}
963
964/// Where option of the [`zmpop`](SortedSetCommands::zmpop) command
965pub enum ZWhere {
966 /// When the MIN modifier is used, the elements popped are those
967 /// with the lowest scores from the first non-empty sorted set.
968 Min,
969 /// The MAX modifier causes elements with the highest scores to be popped.
970 Max,
971}
972
973impl ToArgs for ZWhere {
974 fn write_args(&self, args: &mut CommandArgs) {
975 match self {
976 ZWhere::Min => args.arg("MIN"),
977 ZWhere::Max => args.arg("MAX"),
978 };
979 }
980}
981
982/// Options for the [`zadd`](SortedSetCommands::zadd) command.
983#[derive(Default)]
984pub struct ZAddOptions {
985 command_args: CommandArgs,
986}
987
988impl ZAddOptions {
989 #[must_use]
990 pub fn condition(mut self, condition: ZAddCondition) -> Self {
991 Self {
992 command_args: self.command_args.arg(condition).build(),
993 }
994 }
995
996 #[must_use]
997 pub fn comparison(mut self, comparison: ZAddComparison) -> Self {
998 Self {
999 command_args: self.command_args.arg(comparison).build(),
1000 }
1001 }
1002
1003 #[must_use]
1004 pub fn change(mut self) -> Self {
1005 Self {
1006 command_args: self.command_args.arg("CH").build(),
1007 }
1008 }
1009}
1010
1011impl ToArgs for ZAddOptions {
1012 fn write_args(&self, args: &mut CommandArgs) {
1013 self.command_args.write_args(args);
1014 }
1015}
1016
1017/// Result for [`zmpop`](SortedSetCommands::zmpop) the command.
1018pub type ZMPopResult<E> = (String, Vec<(E, f64)>);
1019
1020/// Options for the [`zrange`](SortedSetCommands::zrange)
1021/// and [`zrangestore`](SortedSetCommands::zrangestore) commands
1022#[derive(Default)]
1023pub struct ZRangeOptions {
1024 command_args: CommandArgs,
1025}
1026
1027impl ZRangeOptions {
1028 #[must_use]
1029 pub fn sort_by(mut self, sort_by: ZRangeSortBy) -> Self {
1030 Self {
1031 command_args: self.command_args.arg(sort_by).build(),
1032 }
1033 }
1034
1035 #[must_use]
1036 pub fn reverse(mut self) -> Self {
1037 Self {
1038 command_args: self.command_args.arg("REV").build(),
1039 }
1040 }
1041
1042 #[must_use]
1043 pub fn limit(mut self, offset: usize, count: isize) -> Self {
1044 Self {
1045 command_args: self
1046 .command_args
1047 .arg("LIMIT")
1048 .arg(offset)
1049 .arg(count)
1050 .build(),
1051 }
1052 }
1053}
1054
1055impl ToArgs for ZRangeOptions {
1056 fn write_args(&self, args: &mut CommandArgs) {
1057 args.arg(&self.command_args);
1058 }
1059}
1060
1061/// Options for the [`zscan`](SortedSetCommands::zscan) command
1062#[derive(Default)]
1063pub struct ZScanOptions {
1064 command_args: CommandArgs,
1065}
1066
1067impl ZScanOptions {
1068 #[must_use]
1069 pub fn match_pattern<P: SingleArg>(mut self, match_pattern: P) -> Self {
1070 Self {
1071 command_args: self.command_args.arg("MATCH").arg(match_pattern).build(),
1072 }
1073 }
1074
1075 #[must_use]
1076 pub fn count(mut self, count: usize) -> Self {
1077 Self {
1078 command_args: self.command_args.arg("COUNT").arg(count).build(),
1079 }
1080 }
1081}
1082
1083impl ToArgs for ZScanOptions {
1084 fn write_args(&self, args: &mut CommandArgs) {
1085 args.arg(&self.command_args);
1086 }
1087}
1088
1089/// Result for the [`zscan`](SortedSetCommands::zscan) command.
1090#[derive(Debug, Deserialize)]
1091pub struct ZScanResult<M>
1092where
1093 M: PrimitiveResponse + DeserializeOwned,
1094{
1095 pub cursor: u64,
1096 #[serde(deserialize_with = "deserialize_vec_of_pairs")]
1097 pub elements: Vec<(M, f64)>,
1098}