td_rredis/
commands.rs

1use types::{FromRedisValue, ToRedisArgs, RedisResult, NumericBehavior};
2use connection::{Connection, ConnectionLike};
3use cmd::{cmd, Cmd, Pipeline, Iter};
4
5
6macro_rules! implement_commands {
7    (
8        $(
9            $(#[$attr:meta])+
10            fn $name:ident<$($tyargs:ident : $ty:ident),*>(
11                $($argname:ident: $argty:ty),*) $body:block
12        )*
13    ) =>
14    (
15/// Implements common redis commands for connection like objects.  This
16/// allows you to send commands straight to a connection or client.  It
17/// is also implemented for redis results of clients which makes for
18/// very convenient access in some basic cases.
19///
20/// This allows you to use nicer syntax for some common operations.
21/// For instance this code:
22///
23/// ```rust,no_run
24/// # fn do_something() -> td_rredis::RedisResult<()> {
25/// let client = try!(td_rredis::Client::open("redis://127.0.0.1/"));
26/// let con = try!(client.get_connection());
27/// td_rredis::cmd("SET").arg("my_key").arg(42).execute(&con);
28/// assert_eq!(td_rredis::cmd("GET").arg("my_key").query(&con), Ok(42));
29/// # Ok(()) }
30/// ```
31///
32/// Will become this:
33///
34/// ```rust,no_run
35/// # fn do_something() -> td_rredis::RedisResult<()> {
36/// use td_rredis::Commands;
37/// let client = try!(td_rredis::Client::open("redis://127.0.0.1/"));
38/// let con = try!(client.get_connection());
39/// assert_eq!(con.get("my_key"), Ok(42));
40/// # Ok(()) }
41/// ```
42        pub trait Commands : ConnectionLike+Sized {
43            $(
44                $(#[$attr])*
45                #[inline]
46                fn $name<$($tyargs: $ty,)* RV: FromRedisValue>(
47                    &self $(, $argname: $argty)*) -> RedisResult<RV>
48                    { ($body).query(self) }
49            )*
50
51/// Incrementally iterate the keys space.
52            #[inline]
53            fn scan<RV: FromRedisValue>(&self) -> RedisResult<Iter<RV>> {
54                cmd("SCAN").cursor_arg(0).iter(self)
55            }
56
57/// Incrementally iterate the keys space for keys matching a pattern.
58            #[inline]
59            fn scan_match<P: ToRedisArgs, RV: FromRedisValue>(&self, pattern: P) -> RedisResult<Iter<RV>> {
60                cmd("SCAN").cursor_arg(0).arg("MATCH").arg(pattern).iter(self)
61            }
62
63/// Incrementally iterate hash fields and associated values.
64            #[inline]
65            fn hscan<K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> RedisResult<Iter<RV>> {
66                cmd("HSCAN").arg(key).cursor_arg(0).iter(self)
67            }
68
69/// Incrementally iterate hash fields and associated values for
70/// field names matching a pattern.
71            #[inline]
72            fn hscan_match<K: ToRedisArgs, P: ToRedisArgs, RV: FromRedisValue>
73                    (&self, key: K, pattern: P) -> RedisResult<Iter<RV>> {
74                cmd("HSCAN").arg(key).cursor_arg(0).arg("MATCH").arg(pattern).iter(self)
75            }
76
77/// Incrementally iterate set elements.
78            #[inline]
79            fn sscan<K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> RedisResult<Iter<RV>> {
80                cmd("SSCAN").arg(key).cursor_arg(0).iter(self)
81            }
82
83/// Incrementally iterate set elements for elements matching a pattern.
84            #[inline]
85            fn sscan_match<K: ToRedisArgs, P: ToRedisArgs, RV: FromRedisValue>
86                    (&self, key: K, pattern: P) -> RedisResult<Iter<RV>> {
87                cmd("SSCAN").arg(key).cursor_arg(0).arg("MATCH").arg(pattern).iter(self)
88            }
89
90/// Incrementally iterate sorted set elements.
91            #[inline]
92            fn zscan<K: ToRedisArgs, RV: FromRedisValue>(&self, key: K) -> RedisResult<Iter<RV>> {
93                cmd("ZSCAN").arg(key).cursor_arg(0).iter(self)
94            }
95
96/// Incrementally iterate sorted set elements for elements matching a pattern.
97            #[inline]
98            fn zscan_match<K: ToRedisArgs, P: ToRedisArgs, RV: FromRedisValue>
99                    (&self, key: K, pattern: P) -> RedisResult<Iter<RV>> {
100                cmd("ZSCAN").arg(key).cursor_arg(0).arg("MATCH").arg(pattern).iter(self)
101            }
102        }
103
104/// Implements common redis commands for pipelines.  Unlike the regular
105/// commands trait, this returns the pipeline rather than a result
106/// directly.  Other than that it works the same however.
107        pub trait PipelineCommands {
108            #[doc(hidden)]
109            #[inline]
110            fn perform(&mut self, con: &Cmd) -> &mut Self;
111
112            $(
113                $(#[$attr])*
114                #[inline]
115                fn $name<'a $(, $tyargs: $ty)*>(
116                    &mut self $(, $argname: $argty)*) -> &mut Self
117                    { self.perform($body) }
118            )*
119        }
120    )
121}
122
123implement_commands! {
124// most common operations
125
126/// Get the value of a key.  If key is a vec this becomes an `MGET`.
127    fn get<K: ToRedisArgs>(key: K) {
128        cmd(if key.is_single_arg() { "GET" } else { "MGET" }).arg(key)
129    }
130
131/// Set the string value of a key.
132    fn set<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
133        cmd("SET").arg(key).arg(value)
134    }
135
136/// Sets multiple keys to their values.
137    fn set_multiple<K: ToRedisArgs, V: ToRedisArgs>(items: &[(K, V)]) {
138        cmd("MSET").arg(items)
139    }
140
141/// Set the value and expiration of a key.
142    fn set_ex<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, seconds: usize) {
143        cmd("SETEX").arg(key).arg(seconds).arg(value)
144    }
145
146/// Set the value of a key, only if the key does not exist
147    fn set_nx<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
148        cmd("SETNX").arg(key).arg(value)
149    }
150
151/// Sets multiple keys to their values failing if at least one already exists.
152    fn mset_nx<K: ToRedisArgs, V: ToRedisArgs>(items: &[(K, V)]) {
153        cmd("MSETNX").arg(items)
154    }
155
156/// Set the string value of a key and return its old value.
157    fn getset<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
158        cmd("GETSET").arg(key).arg(value)
159    }
160
161/// Delete one or more keys.
162    fn del<K: ToRedisArgs>(key: K) {
163        cmd("DEL").arg(key)
164    }
165
166/// Determine if a key exists.
167    fn exists<K: ToRedisArgs>(key: K) {
168        cmd("EXISTS").arg(key)
169    }
170
171/// Set a key's time to live in seconds.
172    fn expire<K: ToRedisArgs>(key: K, seconds: usize) {
173        cmd("EXPIRE").arg(key).arg(seconds)
174    }
175
176/// Set the expiration for a key as a UNIX timestamp.
177    fn expire_at<K: ToRedisArgs>(key: K, ts: usize) {
178        cmd("EXPIREAT").arg(key).arg(ts)
179    }
180
181/// Set a key's time to live in milliseconds.
182    fn pexpire<K: ToRedisArgs>(key: K, ms: usize) {
183        cmd("PEXPIRE").arg(key).arg(ms)
184    }
185
186/// Set the expiration for a key as a UNIX timestamp in milliseconds.
187    fn pexpire_at<K: ToRedisArgs>(key: K, ts: usize) {
188        cmd("PEXPIREAT").arg(key).arg(ts)
189    }
190
191/// Remove the expiration from a key.
192    fn persist<K: ToRedisArgs>(key: K) {
193        cmd("PERSIST").arg(key)
194    }
195
196/// Rename a key.
197    fn rename<K: ToRedisArgs>(key: K, new_key: K) {
198        cmd("RENAME").arg(key).arg(new_key)
199    }
200
201/// Rename a key, only if the new key does not exist.
202    fn rename_nx<K: ToRedisArgs>(key: K, new_key: K) {
203        cmd("RENAMENX").arg(key).arg(new_key)
204    }
205
206// common string operations
207
208/// Append a value to a key.
209    fn append<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
210        cmd("APPEND").arg(key).arg(value)
211    }
212
213/// Increment the numeric value of a key by the given amount.  This
214/// issues a `INCRBY` or `INCRBYFLOAT` depending on the type.
215    fn incr<K: ToRedisArgs, V: ToRedisArgs>(key: K, delta: V) {
216        cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
217            "INCRBYFLOAT"
218        } else {
219            "INCRBY"
220        }).arg(key).arg(delta)
221    }
222
223/// Sets or clears the bit at offset in the string value stored at key.
224    fn setbit<K: ToRedisArgs>(key: K, offset: usize, value: bool) {
225        cmd("SETBIT").arg(key).arg(offset).arg(value)
226    }
227
228/// Returns the bit value at offset in the string value stored at key.
229    fn getbit<K: ToRedisArgs>(key: K, offset: usize) {
230        cmd("GETBIT").arg(key).arg(offset)
231    }
232
233/// Count set bits in a string.
234    fn bitcount<K: ToRedisArgs>(key: K) {
235        cmd("BITCOUNT").arg(key)
236    }
237
238/// Count set bits in a string in a range.
239    fn bitcount_range<K: ToRedisArgs>(key: K, start: usize, end: usize) {
240        cmd("BITCOUNT").arg(key).arg(start).arg(end)
241    }
242
243/// Perform a bitwise AND between multiple keys (containing string values)
244/// and store the result in the destination key.
245    fn bit_and<K: ToRedisArgs>(dstkey: K, srckeys: K) {
246        cmd("BITOP").arg("AND").arg(dstkey).arg(srckeys)
247    }
248
249/// Perform a bitwise OR between multiple keys (containing string values)
250/// and store the result in the destination key.
251    fn bit_or<K: ToRedisArgs>(dstkey: K, srckeys: K) {
252        cmd("BITOP").arg("OR").arg(dstkey).arg(srckeys)
253    }
254
255/// Perform a bitwise XOR between multiple keys (containing string values)
256/// and store the result in the destination key.
257    fn bit_xor<K: ToRedisArgs>(dstkey: K, srckeys: K) {
258        cmd("BITOP").arg("XOR").arg(dstkey).arg(srckeys)
259    }
260
261/// Perform a bitwise NOT of the key (containing string values)
262/// and store the result in the destination key.
263    fn bit_not<K: ToRedisArgs>(dstkey: K, srckey: K) {
264        cmd("BITOP").arg("NOT").arg(dstkey).arg(srckey)
265    }
266
267/// Get the length of the value stored in a key.
268    fn strlen<K: ToRedisArgs>(key: K) {
269        cmd("STRLEN").arg(key)
270    }
271
272// hash operations
273
274/// Gets a single (or multiple) fields from a hash.
275    fn hget<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
276        cmd(if field.is_single_arg() { "HGET" } else { "HMGET" }).arg(key).arg(field)
277    }
278
279/// Deletes a single (or multiple) fields from a hash.
280    fn hdel<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
281        cmd("HDEL").arg(key).arg(field)
282    }
283
284/// Sets a single field in a hash.
285    fn hset<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
286        cmd("HSET").arg(key).arg(field).arg(value)
287    }
288
289/// Sets a single field in a hash if it does not exist.
290    fn hset_nx<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
291        cmd("HSETNX").arg(key).arg(field).arg(value)
292    }
293
294/// Sets a multiple fields in a hash.
295    fn hset_multiple<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, items: &[(F, V)]) {
296        cmd("HMSET").arg(key).arg(items)
297    }
298
299/// Increments a value.
300    fn hincr<K: ToRedisArgs, F: ToRedisArgs, D: ToRedisArgs>(key: K, field: F, delta: D) {
301        cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
302            "HINCRBYFLOAT"
303        } else {
304            "HINCRBY"
305        }).arg(key).arg(field).arg(delta)
306    }
307
308/// Checks if a field in a hash exists.
309    fn hexists<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
310        cmd("HEXISTS").arg(key).arg(field)
311    }
312
313/// Gets all the keys in a hash.
314    fn hkeys<K: ToRedisArgs>(key: K) {
315        cmd("HKEYS").arg(key)
316    }
317
318/// Gets all the values in a hash.
319    fn hvals<K: ToRedisArgs>(key: K) {
320        cmd("HVALS").arg(key)
321    }
322
323/// Gets all the fields and values in a hash.
324    fn hgetall<K: ToRedisArgs>(key: K) {
325        cmd("HGETALL").arg(key)
326    }
327
328/// Gets the length of a hash.
329    fn hlen<K: ToRedisArgs>(key: K) {
330        cmd("HLEN").arg(key)
331    }
332
333// list operations
334
335/// Remove and get the first element in a list, or block until one is available.
336    fn blpop<K: ToRedisArgs>(key: K, timeout: usize) {
337        cmd("BLPOP").arg(key).arg(timeout)
338    }
339
340/// Remove and get the last element in a list, or block until one is available.
341    fn brpop<K: ToRedisArgs>(key: K, timeout: usize) {
342        cmd("BRPOP").arg(key).arg(timeout)
343    }
344
345/// Pop a value from a list, push it to another list and return it;
346/// or block until one is available.
347    fn brpoplpush<K: ToRedisArgs>(srckey: K, dstkey: K, timeout: usize) {
348        cmd("BRPOPLPUSH").arg(srckey).arg(dstkey).arg(timeout)
349    }
350
351/// Get an element from a list by its index.
352    fn lindex<K: ToRedisArgs>(key: K, index: isize) {
353        cmd("LINDEX").arg(key).arg(index)
354    }
355
356/// Insert an element before another element in a list.
357    fn linsert_before<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
358            key: K, pivot: P, value: V) {
359        cmd("LINSERT").arg(key).arg("BEFORE").arg(pivot).arg(value)
360    }
361
362/// Insert an element after another element in a list.
363    fn linsert_after<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
364            key: K, pivot: P, value: V) {
365        cmd("LINSERT").arg(key).arg("AFTER").arg(pivot).arg(value)
366    }
367
368/// Returns the length of the list stored at key.
369    fn llen<K: ToRedisArgs>(key: K) {
370        cmd("LLEN").arg(key)
371    }
372
373/// Removes and returns the first element of the list stored at key.
374    fn lpop<K: ToRedisArgs>(key: K) {
375        cmd("LPOP").arg(key)
376    }
377
378/// Insert all the specified values at the head of the list stored at key.
379    fn lpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
380        cmd("LPUSH").arg(key).arg(value)
381    }
382
383/// Inserts a value at the head of the list stored at key, only if key
384/// already exists and holds a list.
385    fn lpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
386        cmd("LPUSHX").arg(key).arg(value)
387    }
388
389/// Returns the specified elements of the list stored at key.
390    fn lrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
391        cmd("LRANGE").arg(key).arg(start).arg(stop)
392    }
393
394/// Removes the first count occurrences of elements equal to value
395/// from the list stored at key.
396    fn lrem<K: ToRedisArgs, V: ToRedisArgs>(key: K, count: isize, value: V) {
397        cmd("LREM").arg(key).arg(count).arg(value)
398    }
399
400/// Trim an existing list so that it will contain only the specified
401/// range of elements specified.
402    fn ltrim<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
403        cmd("LTRIM").arg(key).arg(start).arg(stop)
404    }
405
406/// Removes and returns the last element of the list stored at key.
407    fn rpop<K: ToRedisArgs>(key: K) {
408        cmd("RPOP").arg(key)
409    }
410
411/// Pop a value from a list, push it to another list and return it.
412    fn rpoplpush<K: ToRedisArgs>(key: K, dstkey: K) {
413        cmd("RPOPLPUSH").arg(key).arg(dstkey)
414    }
415
416/// Insert all the specified values at the tail of the list stored at key.
417    fn rpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
418        cmd("RPUSH").arg(key).arg(value)
419    }
420
421/// Inserts value at the tail of the list stored at key, only if key
422/// already exists and holds a list.
423    fn rpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
424        cmd("RPUSHX").arg(key).arg(value)
425    }
426
427// set commands
428
429/// Add one or more members to a set.
430    fn sadd<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
431        cmd("SADD").arg(key).arg(member)
432    }
433
434/// Get the number of members in a set.
435    fn scard<K: ToRedisArgs>(key: K) {
436        cmd("SCARD").arg(key)
437    }
438
439/// Subtract multiple sets.
440    fn sdiff<K: ToRedisArgs>(keys: K) {
441        cmd("SDIFF").arg(keys)
442    }
443
444/// Subtract multiple sets and store the resulting set in a key.
445    fn sdiffstore<K: ToRedisArgs>(dstkey: K, keys: K) {
446        cmd("SDIFFSTORE").arg(dstkey).arg(keys)
447    }
448
449/// Intersect multiple sets.
450    fn sinter<K: ToRedisArgs>(keys: K) {
451        cmd("SINTER").arg(keys)
452    }
453
454/// Intersect multiple sets and store the resulting set in a key.
455    fn sdinterstore<K: ToRedisArgs>(dstkey: K, keys: K) {
456        cmd("SINTERSTORE").arg(dstkey).arg(keys)
457    }
458
459/// Determine if a given value is a member of a set.
460    fn sismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
461        cmd("SISMEMBER").arg(key).arg(member)
462    }
463
464/// Get all the members in a set.
465    fn smembers<K: ToRedisArgs>(key: K) {
466        cmd("SMEMBERS").arg(key)
467    }
468
469/// Move a member from one set to another.
470    fn smove<K: ToRedisArgs, M: ToRedisArgs>(srckey: K, dstkey: K, member: M) {
471        cmd("SMOVE").arg(srckey).arg(dstkey).arg(member)
472    }
473
474/// Remove and return a random member from a set.
475    fn spop<K: ToRedisArgs>(key: K) {
476        cmd("SPOP").arg(key)
477    }
478
479/// Get one random member from a set.
480    fn srandmember<K: ToRedisArgs>(key: K) {
481        cmd("SRANDMEMBER").arg(key)
482    }
483
484/// Get multiple random members from a set.
485    fn srandmember_multiple<K: ToRedisArgs>(key: K, count: usize) {
486        cmd("SRANDMEMBER").arg(key).arg(count)
487    }
488
489/// Remove one or more members from a set.
490    fn srem<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
491        cmd("SREM").arg(key).arg(member)
492    }
493
494/// Add multiple sets.
495    fn sunion<K: ToRedisArgs>(keys: K) {
496        cmd("SUNION").arg(keys)
497    }
498
499/// Add multiple sets and store the resulting set in a key.
500    fn sunionstore<K: ToRedisArgs>(dstkey: K, keys: K) {
501        cmd("SUNIONSTORE").arg(dstkey).arg(keys)
502    }
503
504// sorted set commands
505
506/// Add one member to a sorted set, or update its score if it already exists.
507    fn zadd<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, member: M, score: S) {
508        cmd("ZADD").arg(key).arg(score).arg(member)
509    }
510
511/// Add multiple members to a sorted set, or update its score if it already exists.
512    fn zadd_multiple<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, items: &[(S, M)]) {
513        cmd("ZADD").arg(key).arg(items)
514    }
515
516/// Get the number of members in a sorted set.
517    fn zcard<K: ToRedisArgs>(key: K) {
518        cmd("ZCARD").arg(key)
519    }
520
521/// Count the members in a sorted set with scores within the given values.
522    fn zcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
523        cmd("ZCOUNT").arg(key).arg(min).arg(max)
524    }
525
526/// Increments the member in a sorted set at key by delta.
527/// If the member does not exist, it is added with delta as its score.
528    fn zincr<K: ToRedisArgs, M: ToRedisArgs, D: ToRedisArgs>(key: K, member: M, delta: D) {
529        cmd("ZINCRBY").arg(key).arg(delta).arg(member)
530    }
531
532/// Intersect multiple sorted sets and store the resulting sorted set in
533/// a new key using SUM as aggregation function.
534    fn zinterstore<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
535        cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys)
536    }
537
538/// Intersect multiple sorted sets and store the resulting sorted set in
539/// a new key using MIN as aggregation function.
540    fn zinterstore_min<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
541        cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MIN")
542    }
543
544/// Intersect multiple sorted sets and store the resulting sorted set in
545/// a new key using MAX as aggregation function.
546    fn zinterstore_max<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
547        cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MAX")
548    }
549
550/// Count the number of members in a sorted set between a given lexicographical range.
551    fn zlexcount<K: ToRedisArgs, L: ToRedisArgs>(key: K, min: L, max: L) {
552        cmd("ZLEXCOUNT").arg(key).arg(min).arg(max)
553    }
554
555/// Return a range of members in a sorted set, by index
556    fn zrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
557        cmd("ZRANGE").arg(key).arg(start).arg(stop)
558    }
559
560/// Return a range of members in a sorted set, by index with scores.
561    fn zrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
562        cmd("ZRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
563    }
564
565/// Return a range of members in a sorted set, by lexicographical range.
566    fn zrangebylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
567        cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max)
568    }
569
570/// Return a range of members in a sorted set, by lexicographical
571/// range with offset and limit.
572    fn zrangebylex_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(
573            key: K, min: M, max: MM, offset: isize, count: isize) {
574        cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
575    }
576
577/// Return a range of members in a sorted set, by lexicographical range.
578    fn zrevrangebylex<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
579        cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min)
580    }
581
582/// Return a range of members in a sorted set, by lexicographical
583/// range with offset and limit.
584    fn zrevrangebylex_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(
585            key: K, max: MM, min: M, offset: isize, count: isize) {
586        cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
587    }
588
589/// Return a range of members in a sorted set, by score.
590    fn zrangebyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
591        cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max)
592    }
593
594/// Return a range of members in a sorted set, by score with scores.
595    fn zrangebyscore_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
596        cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
597    }
598
599/// Return a range of members in a sorted set, by score with limit.
600    fn zrangebyscore_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
601            (key: K, min: M, max: MM, offset: isize, count: isize) {
602        cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
603    }
604
605/// Return a range of members in a sorted set, by score with limit with scores.
606    fn zrangebyscore_limit_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
607            (key: K, min: M, max: MM, offset: isize, count: isize) {
608        cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
609            .arg("LIMIT").arg(offset).arg(count)
610    }
611
612/// Determine the index of a member in a sorted set.
613    fn zrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
614        cmd("ZRANK").arg(key).arg(member)
615    }
616
617/// Remove one or more members from a sorted set.
618    fn zrem<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
619        cmd("ZREM").arg(key).arg(members)
620    }
621
622/// Remove all members in a sorted set between the given lexicographical range.
623    fn zrembylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
624        cmd("ZREMBYLEX").arg(key).arg(min).arg(max)
625    }
626
627/// Remove all members in a sorted set within the given indexes.
628    fn zrembyrank<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
629        cmd("ZREMBYRANK").arg(key).arg(start).arg(stop)
630    }
631
632/// Remove all members in a sorted set within the given scores.
633    fn zrembyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
634        cmd("ZREMRANGEBYSCORE").arg(key).arg(min).arg(max)
635    }
636
637/// Return a range of members in a sorted set, by index, with scores
638/// ordered from high to low.
639    fn zrevrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
640        cmd("ZREVRANGE").arg(key).arg(start).arg(stop)
641    }
642
643/// Return a range of members in a sorted set, by index, with scores
644/// ordered from high to low.
645    fn zrevrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
646        cmd("ZREVRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
647    }
648
649/// Return a range of members in a sorted set, by score.
650    fn zrevrangebyscore<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
651        cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min)
652    }
653
654/// Return a range of members in a sorted set, by score with scores.
655    fn zrevrangebyscore_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
656        cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
657    }
658
659/// Return a range of members in a sorted set, by score with limit.
660    fn zrevrangebyscore_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
661            (key: K, max: MM, min: M, offset: isize, count: isize) {
662        cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
663    }
664
665/// Return a range of members in a sorted set, by score with limit with scores.
666    fn zrevrangebyscore_limit_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
667            (key: K, max: MM, min: M, offset: isize, count: isize) {
668        cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
669            .arg("LIMIT").arg(offset).arg(count)
670    }
671
672/// Determine the index of a member in a sorted set, with scores ordered from high to low.
673    fn zrevrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
674        cmd("ZREVRANK").arg(key).arg(member)
675    }
676
677/// Get the score associated with the given member in a sorted set.
678    fn zscore<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
679        cmd("ZSCORE").arg(key).arg(member)
680    }
681
682/// Unions multiple sorted sets and store the resulting sorted set in
683/// a new key using SUM as aggregation function.
684    fn zunionstore<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
685        cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys)
686    }
687
688/// Unions multiple sorted sets and store the resulting sorted set in
689/// a new key using MIN as aggregation function.
690    fn zunionstore_min<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
691        cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MIN")
692    }
693
694/// Unions multiple sorted sets and store the resulting sorted set in
695/// a new key using MAX as aggregation function.
696    fn zunionstore_max<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
697        cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MAX")
698    }
699
700// hyperloglog commands
701
702/// Adds the specified elements to the specified HyperLogLog.
703    fn pfadd<K: ToRedisArgs, E: ToRedisArgs>(key: K, element: E) {
704        cmd("PFADD").arg(key).arg(element)
705    }
706
707/// Return the approximated cardinality of the set(s) observed by the
708/// HyperLogLog at key(s).
709    fn pfcount<K: ToRedisArgs>(key: K) {
710        cmd("PFCOUNT").arg(key)
711    }
712
713/// Merge N different HyperLogLogs into a single one.
714    fn pfmerge<K: ToRedisArgs>(dstkey: K, srckeys: K) {
715        cmd("PFMERGE").arg(dstkey).arg(srckeys)
716    }
717}
718
719impl Commands for Connection {}
720// impl Commands for Client {}
721
722impl PipelineCommands for Pipeline {
723    fn perform(&mut self, cmd: &Cmd) -> &mut Pipeline {
724        self.add_command(cmd)
725    }
726}