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}