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 (
15pub 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#[inline]
53 fn scan<RV: FromRedisValue>(&self) -> RedisResult<Iter<RV>> {
54 cmd("SCAN").cursor_arg(0).iter(self)
55 }
56
57#[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#[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#[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#[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#[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#[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#[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
104pub 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! {
124fn get<K: ToRedisArgs>(key: K) {
128 cmd(if key.is_single_arg() { "GET" } else { "MGET" }).arg(key)
129 }
130
131fn set<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
133 cmd("SET").arg(key).arg(value)
134 }
135
136fn set_multiple<K: ToRedisArgs, V: ToRedisArgs>(items: &[(K, V)]) {
138 cmd("MSET").arg(items)
139 }
140
141fn set_ex<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, seconds: usize) {
143 cmd("SETEX").arg(key).arg(seconds).arg(value)
144 }
145
146fn set_nx<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
148 cmd("SETNX").arg(key).arg(value)
149 }
150
151fn mset_nx<K: ToRedisArgs, V: ToRedisArgs>(items: &[(K, V)]) {
153 cmd("MSETNX").arg(items)
154 }
155
156fn getset<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
158 cmd("GETSET").arg(key).arg(value)
159 }
160
161fn del<K: ToRedisArgs>(key: K) {
163 cmd("DEL").arg(key)
164 }
165
166fn exists<K: ToRedisArgs>(key: K) {
168 cmd("EXISTS").arg(key)
169 }
170
171fn expire<K: ToRedisArgs>(key: K, seconds: usize) {
173 cmd("EXPIRE").arg(key).arg(seconds)
174 }
175
176fn expire_at<K: ToRedisArgs>(key: K, ts: usize) {
178 cmd("EXPIREAT").arg(key).arg(ts)
179 }
180
181fn pexpire<K: ToRedisArgs>(key: K, ms: usize) {
183 cmd("PEXPIRE").arg(key).arg(ms)
184 }
185
186fn pexpire_at<K: ToRedisArgs>(key: K, ts: usize) {
188 cmd("PEXPIREAT").arg(key).arg(ts)
189 }
190
191fn persist<K: ToRedisArgs>(key: K) {
193 cmd("PERSIST").arg(key)
194 }
195
196fn rename<K: ToRedisArgs>(key: K, new_key: K) {
198 cmd("RENAME").arg(key).arg(new_key)
199 }
200
201fn rename_nx<K: ToRedisArgs>(key: K, new_key: K) {
203 cmd("RENAMENX").arg(key).arg(new_key)
204 }
205
206fn append<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
210 cmd("APPEND").arg(key).arg(value)
211 }
212
213fn 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
223fn setbit<K: ToRedisArgs>(key: K, offset: usize, value: bool) {
225 cmd("SETBIT").arg(key).arg(offset).arg(value)
226 }
227
228fn getbit<K: ToRedisArgs>(key: K, offset: usize) {
230 cmd("GETBIT").arg(key).arg(offset)
231 }
232
233fn bitcount<K: ToRedisArgs>(key: K) {
235 cmd("BITCOUNT").arg(key)
236 }
237
238fn bitcount_range<K: ToRedisArgs>(key: K, start: usize, end: usize) {
240 cmd("BITCOUNT").arg(key).arg(start).arg(end)
241 }
242
243fn bit_and<K: ToRedisArgs>(dstkey: K, srckeys: K) {
246 cmd("BITOP").arg("AND").arg(dstkey).arg(srckeys)
247 }
248
249fn bit_or<K: ToRedisArgs>(dstkey: K, srckeys: K) {
252 cmd("BITOP").arg("OR").arg(dstkey).arg(srckeys)
253 }
254
255fn bit_xor<K: ToRedisArgs>(dstkey: K, srckeys: K) {
258 cmd("BITOP").arg("XOR").arg(dstkey).arg(srckeys)
259 }
260
261fn bit_not<K: ToRedisArgs>(dstkey: K, srckey: K) {
264 cmd("BITOP").arg("NOT").arg(dstkey).arg(srckey)
265 }
266
267fn strlen<K: ToRedisArgs>(key: K) {
269 cmd("STRLEN").arg(key)
270 }
271
272fn 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
279fn hdel<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
281 cmd("HDEL").arg(key).arg(field)
282 }
283
284fn hset<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
286 cmd("HSET").arg(key).arg(field).arg(value)
287 }
288
289fn 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
294fn hset_multiple<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, items: &[(F, V)]) {
296 cmd("HMSET").arg(key).arg(items)
297 }
298
299fn 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
308fn hexists<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
310 cmd("HEXISTS").arg(key).arg(field)
311 }
312
313fn hkeys<K: ToRedisArgs>(key: K) {
315 cmd("HKEYS").arg(key)
316 }
317
318fn hvals<K: ToRedisArgs>(key: K) {
320 cmd("HVALS").arg(key)
321 }
322
323fn hgetall<K: ToRedisArgs>(key: K) {
325 cmd("HGETALL").arg(key)
326 }
327
328fn hlen<K: ToRedisArgs>(key: K) {
330 cmd("HLEN").arg(key)
331 }
332
333fn blpop<K: ToRedisArgs>(key: K, timeout: usize) {
337 cmd("BLPOP").arg(key).arg(timeout)
338 }
339
340fn brpop<K: ToRedisArgs>(key: K, timeout: usize) {
342 cmd("BRPOP").arg(key).arg(timeout)
343 }
344
345fn brpoplpush<K: ToRedisArgs>(srckey: K, dstkey: K, timeout: usize) {
348 cmd("BRPOPLPUSH").arg(srckey).arg(dstkey).arg(timeout)
349 }
350
351fn lindex<K: ToRedisArgs>(key: K, index: isize) {
353 cmd("LINDEX").arg(key).arg(index)
354 }
355
356fn 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
362fn 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
368fn llen<K: ToRedisArgs>(key: K) {
370 cmd("LLEN").arg(key)
371 }
372
373fn lpop<K: ToRedisArgs>(key: K) {
375 cmd("LPOP").arg(key)
376 }
377
378fn lpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
380 cmd("LPUSH").arg(key).arg(value)
381 }
382
383fn lpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
386 cmd("LPUSHX").arg(key).arg(value)
387 }
388
389fn lrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
391 cmd("LRANGE").arg(key).arg(start).arg(stop)
392 }
393
394fn lrem<K: ToRedisArgs, V: ToRedisArgs>(key: K, count: isize, value: V) {
397 cmd("LREM").arg(key).arg(count).arg(value)
398 }
399
400fn ltrim<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
403 cmd("LTRIM").arg(key).arg(start).arg(stop)
404 }
405
406fn rpop<K: ToRedisArgs>(key: K) {
408 cmd("RPOP").arg(key)
409 }
410
411fn rpoplpush<K: ToRedisArgs>(key: K, dstkey: K) {
413 cmd("RPOPLPUSH").arg(key).arg(dstkey)
414 }
415
416fn rpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
418 cmd("RPUSH").arg(key).arg(value)
419 }
420
421fn rpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
424 cmd("RPUSHX").arg(key).arg(value)
425 }
426
427fn sadd<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
431 cmd("SADD").arg(key).arg(member)
432 }
433
434fn scard<K: ToRedisArgs>(key: K) {
436 cmd("SCARD").arg(key)
437 }
438
439fn sdiff<K: ToRedisArgs>(keys: K) {
441 cmd("SDIFF").arg(keys)
442 }
443
444fn sdiffstore<K: ToRedisArgs>(dstkey: K, keys: K) {
446 cmd("SDIFFSTORE").arg(dstkey).arg(keys)
447 }
448
449fn sinter<K: ToRedisArgs>(keys: K) {
451 cmd("SINTER").arg(keys)
452 }
453
454fn sdinterstore<K: ToRedisArgs>(dstkey: K, keys: K) {
456 cmd("SINTERSTORE").arg(dstkey).arg(keys)
457 }
458
459fn sismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
461 cmd("SISMEMBER").arg(key).arg(member)
462 }
463
464fn smembers<K: ToRedisArgs>(key: K) {
466 cmd("SMEMBERS").arg(key)
467 }
468
469fn smove<K: ToRedisArgs, M: ToRedisArgs>(srckey: K, dstkey: K, member: M) {
471 cmd("SMOVE").arg(srckey).arg(dstkey).arg(member)
472 }
473
474fn spop<K: ToRedisArgs>(key: K) {
476 cmd("SPOP").arg(key)
477 }
478
479fn srandmember<K: ToRedisArgs>(key: K) {
481 cmd("SRANDMEMBER").arg(key)
482 }
483
484fn srandmember_multiple<K: ToRedisArgs>(key: K, count: usize) {
486 cmd("SRANDMEMBER").arg(key).arg(count)
487 }
488
489fn srem<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
491 cmd("SREM").arg(key).arg(member)
492 }
493
494fn sunion<K: ToRedisArgs>(keys: K) {
496 cmd("SUNION").arg(keys)
497 }
498
499fn sunionstore<K: ToRedisArgs>(dstkey: K, keys: K) {
501 cmd("SUNIONSTORE").arg(dstkey).arg(keys)
502 }
503
504fn zadd<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, member: M, score: S) {
508 cmd("ZADD").arg(key).arg(score).arg(member)
509 }
510
511fn zadd_multiple<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, items: &[(S, M)]) {
513 cmd("ZADD").arg(key).arg(items)
514 }
515
516fn zcard<K: ToRedisArgs>(key: K) {
518 cmd("ZCARD").arg(key)
519 }
520
521fn zcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
523 cmd("ZCOUNT").arg(key).arg(min).arg(max)
524 }
525
526fn zincr<K: ToRedisArgs, M: ToRedisArgs, D: ToRedisArgs>(key: K, member: M, delta: D) {
529 cmd("ZINCRBY").arg(key).arg(delta).arg(member)
530 }
531
532fn zinterstore<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
535 cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys)
536 }
537
538fn zinterstore_min<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
541 cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MIN")
542 }
543
544fn zinterstore_max<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
547 cmd("ZINTERSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MAX")
548 }
549
550fn zlexcount<K: ToRedisArgs, L: ToRedisArgs>(key: K, min: L, max: L) {
552 cmd("ZLEXCOUNT").arg(key).arg(min).arg(max)
553 }
554
555fn zrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
557 cmd("ZRANGE").arg(key).arg(start).arg(stop)
558 }
559
560fn zrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
562 cmd("ZRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
563 }
564
565fn zrangebylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
567 cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max)
568 }
569
570fn 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
577fn zrevrangebylex<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
579 cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min)
580 }
581
582fn 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
589fn zrangebyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
591 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max)
592 }
593
594fn 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
599fn 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
605fn 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
612fn zrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
614 cmd("ZRANK").arg(key).arg(member)
615 }
616
617fn zrem<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
619 cmd("ZREM").arg(key).arg(members)
620 }
621
622fn zrembylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
624 cmd("ZREMBYLEX").arg(key).arg(min).arg(max)
625 }
626
627fn zrembyrank<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
629 cmd("ZREMBYRANK").arg(key).arg(start).arg(stop)
630 }
631
632fn zrembyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
634 cmd("ZREMRANGEBYSCORE").arg(key).arg(min).arg(max)
635 }
636
637fn zrevrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
640 cmd("ZREVRANGE").arg(key).arg(start).arg(stop)
641 }
642
643fn zrevrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
646 cmd("ZREVRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
647 }
648
649fn zrevrangebyscore<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
651 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min)
652 }
653
654fn 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
659fn 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
665fn 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
672fn zrevrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
674 cmd("ZREVRANK").arg(key).arg(member)
675 }
676
677fn zscore<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
679 cmd("ZSCORE").arg(key).arg(member)
680 }
681
682fn zunionstore<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
685 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys)
686 }
687
688fn zunionstore_min<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
691 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MIN")
692 }
693
694fn zunionstore_max<K: ToRedisArgs>(dstkey: K, keys: &[K]) {
697 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.len()).arg(keys).arg("AGGREGATE").arg("MAX")
698 }
699
700fn pfadd<K: ToRedisArgs, E: ToRedisArgs>(key: K, element: E) {
704 cmd("PFADD").arg(key).arg(element)
705 }
706
707fn pfcount<K: ToRedisArgs>(key: K) {
710 cmd("PFCOUNT").arg(key)
711 }
712
713fn pfmerge<K: ToRedisArgs>(dstkey: K, srckeys: K) {
715 cmd("PFMERGE").arg(dstkey).arg(srckeys)
716 }
717}
718
719impl Commands for Connection {}
720impl PipelineCommands for Pipeline {
723 fn perform(&mut self, cmd: &Cmd) -> &mut Pipeline {
724 self.add_command(cmd)
725 }
726}