redis_driver/commands/
sorted_set_commands.rs

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