1use crate::cmd::{cmd, Cmd, Iter};
2use crate::connection::{Connection, ConnectionLike, Msg};
3use crate::pipeline::Pipeline;
4use crate::types::{
5 ExistenceCheck, ExpireOption, Expiry, FromRedisValue, NumericBehavior, RedisResult, RedisWrite,
6 SetExpiry, ToRedisArgs,
7};
8
9#[macro_use]
10mod macros;
11
12#[cfg(feature = "json")]
13#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
14mod json;
15
16#[cfg(feature = "json")]
17pub use json::JsonCommands;
18
19#[cfg(all(feature = "json", feature = "aio"))]
20pub use json::JsonAsyncCommands;
21
22#[cfg(feature = "cluster")]
23use crate::cluster_pipeline::ClusterPipeline;
24
25#[cfg(feature = "geospatial")]
26use crate::geo;
27
28#[cfg(feature = "streams")]
29use crate::streams;
30
31#[cfg(feature = "acl")]
32use crate::acl;
33use crate::RedisConnectionInfo;
34
35#[cfg(any(feature = "cluster", feature = "cache-aio"))]
36pub(crate) fn is_readonly_cmd(cmd: &[u8]) -> bool {
37 matches!(
38 cmd,
39 b"BITCOUNT"
40 | b"BITFIELD_RO"
41 | b"BITPOS"
42 | b"DBSIZE"
43 | b"DUMP"
44 | b"EVALSHA_RO"
45 | b"EVAL_RO"
46 | b"EXISTS"
47 | b"EXPIRETIME"
48 | b"FCALL_RO"
49 | b"GEODIST"
50 | b"GEOHASH"
51 | b"GEOPOS"
52 | b"GEORADIUSBYMEMBER_RO"
53 | b"GEORADIUS_RO"
54 | b"GEOSEARCH"
55 | b"GET"
56 | b"GETBIT"
57 | b"GETRANGE"
58 | b"HEXISTS"
59 | b"HEXPIRETIME"
60 | b"HGET"
61 | b"HGETALL"
62 | b"HKEYS"
63 | b"HLEN"
64 | b"HMGET"
65 | b"HRANDFIELD"
66 | b"HPTTL"
67 | b"HPEXPIRETIME"
68 | b"HSCAN"
69 | b"HSTRLEN"
70 | b"HTTL"
71 | b"HVALS"
72 | b"KEYS"
73 | b"LCS"
74 | b"LINDEX"
75 | b"LLEN"
76 | b"LOLWUT"
77 | b"LPOS"
78 | b"LRANGE"
79 | b"MEMORY USAGE"
80 | b"MGET"
81 | b"OBJECT ENCODING"
82 | b"OBJECT FREQ"
83 | b"OBJECT IDLETIME"
84 | b"OBJECT REFCOUNT"
85 | b"PEXPIRETIME"
86 | b"PFCOUNT"
87 | b"PTTL"
88 | b"RANDOMKEY"
89 | b"SCAN"
90 | b"SCARD"
91 | b"SDIFF"
92 | b"SINTER"
93 | b"SINTERCARD"
94 | b"SISMEMBER"
95 | b"SMEMBERS"
96 | b"SMISMEMBER"
97 | b"SORT_RO"
98 | b"SRANDMEMBER"
99 | b"SSCAN"
100 | b"STRLEN"
101 | b"SUBSTR"
102 | b"SUNION"
103 | b"TOUCH"
104 | b"TTL"
105 | b"TYPE"
106 | b"XINFO CONSUMERS"
107 | b"XINFO GROUPS"
108 | b"XINFO STREAM"
109 | b"XLEN"
110 | b"XPENDING"
111 | b"XRANGE"
112 | b"XREAD"
113 | b"XREVRANGE"
114 | b"ZCARD"
115 | b"ZCOUNT"
116 | b"ZDIFF"
117 | b"ZINTER"
118 | b"ZINTERCARD"
119 | b"ZLEXCOUNT"
120 | b"ZMSCORE"
121 | b"ZRANDMEMBER"
122 | b"ZRANGE"
123 | b"ZRANGEBYLEX"
124 | b"ZRANGEBYSCORE"
125 | b"ZRANK"
126 | b"ZREVRANGE"
127 | b"ZREVRANGEBYLEX"
128 | b"ZREVRANGEBYSCORE"
129 | b"ZREVRANK"
130 | b"ZSCAN"
131 | b"ZSCORE"
132 | b"ZUNION"
133 | b"JSON.GET"
134 | b"JSON.MGET"
135 )
136}
137
138implement_commands! {
139 'a
140 fn get<K: ToRedisArgs>(key: K) {
144 cmd(if key.num_of_args() <= 1 { "GET" } else { "MGET" }).arg(key)
145 }
146
147 fn mget<K: ToRedisArgs>(key: K){
149 cmd("MGET").arg(key)
150 }
151
152 fn keys<K: ToRedisArgs>(key: K) {
154 cmd("KEYS").arg(key)
155 }
156
157 fn set<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
159 cmd("SET").arg(key).arg(value)
160 }
161
162 fn set_options<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, options: SetOptions) {
164 cmd("SET").arg(key).arg(value).arg(options)
165 }
166
167 #[allow(deprecated)]
169 #[deprecated(since = "0.22.4", note = "Renamed to mset() to reflect Redis name")]
170 fn set_multiple<K: ToRedisArgs, V: ToRedisArgs>(items: &'a [(K, V)]) {
171 cmd("MSET").arg(items)
172 }
173
174 fn mset<K: ToRedisArgs, V: ToRedisArgs>(items: &'a [(K, V)]) {
176 cmd("MSET").arg(items)
177 }
178
179 fn set_ex<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, seconds: u64) {
181 cmd("SETEX").arg(key).arg(seconds).arg(value)
182 }
183
184 fn pset_ex<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, milliseconds: u64) {
186 cmd("PSETEX").arg(key).arg(milliseconds).arg(value)
187 }
188
189 fn set_nx<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
191 cmd("SETNX").arg(key).arg(value)
192 }
193
194 fn mset_nx<K: ToRedisArgs, V: ToRedisArgs>(items: &'a [(K, V)]) {
196 cmd("MSETNX").arg(items)
197 }
198
199 fn getset<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
201 cmd("GETSET").arg(key).arg(value)
202 }
203
204 fn getrange<K: ToRedisArgs>(key: K, from: isize, to: isize) {
206 cmd("GETRANGE").arg(key).arg(from).arg(to)
207 }
208
209 fn setrange<K: ToRedisArgs, V: ToRedisArgs>(key: K, offset: isize, value: V) {
211 cmd("SETRANGE").arg(key).arg(offset).arg(value)
212 }
213
214 fn del<K: ToRedisArgs>(key: K) {
216 cmd("DEL").arg(key)
217 }
218
219 fn exists<K: ToRedisArgs>(key: K) {
221 cmd("EXISTS").arg(key)
222 }
223
224 fn key_type<K: ToRedisArgs>(key: K) {
226 cmd("TYPE").arg(key)
227 }
228
229 fn expire<K: ToRedisArgs>(key: K, seconds: i64) {
231 cmd("EXPIRE").arg(key).arg(seconds)
232 }
233
234 fn expire_at<K: ToRedisArgs>(key: K, ts: i64) {
236 cmd("EXPIREAT").arg(key).arg(ts)
237 }
238
239 fn pexpire<K: ToRedisArgs>(key: K, ms: i64) {
241 cmd("PEXPIRE").arg(key).arg(ms)
242 }
243
244 fn pexpire_at<K: ToRedisArgs>(key: K, ts: i64) {
246 cmd("PEXPIREAT").arg(key).arg(ts)
247 }
248
249 fn expire_time<K: ToRedisArgs>(key: K) {
251 cmd("EXPIRETIME").arg(key)
252 }
253
254 fn pexpire_time<K: ToRedisArgs>(key: K) {
256 cmd("PEXPIRETIME").arg(key)
257 }
258
259 fn persist<K: ToRedisArgs>(key: K) {
261 cmd("PERSIST").arg(key)
262 }
263
264 fn ttl<K: ToRedisArgs>(key: K) {
266 cmd("TTL").arg(key)
267 }
268
269 fn pttl<K: ToRedisArgs>(key: K) {
271 cmd("PTTL").arg(key)
272 }
273
274 fn get_ex<K: ToRedisArgs>(key: K, expire_at: Expiry) {
276 let (option, time_arg) = match expire_at {
277 Expiry::EX(sec) => ("EX", Some(sec)),
278 Expiry::PX(ms) => ("PX", Some(ms)),
279 Expiry::EXAT(timestamp_sec) => ("EXAT", Some(timestamp_sec)),
280 Expiry::PXAT(timestamp_ms) => ("PXAT", Some(timestamp_ms)),
281 Expiry::PERSIST => ("PERSIST", None),
282 };
283
284 cmd("GETEX").arg(key).arg(option).arg(time_arg)
285 }
286
287 fn get_del<K: ToRedisArgs>(key: K) {
289 cmd("GETDEL").arg(key)
290 }
291
292 fn rename<K: ToRedisArgs, N: ToRedisArgs>(key: K, new_key: N) {
294 cmd("RENAME").arg(key).arg(new_key)
295 }
296
297 fn rename_nx<K: ToRedisArgs, N: ToRedisArgs>(key: K, new_key: N) {
299 cmd("RENAMENX").arg(key).arg(new_key)
300 }
301
302 fn unlink<K: ToRedisArgs>(key: K) {
304 cmd("UNLINK").arg(key)
305 }
306
307 fn append<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
311 cmd("APPEND").arg(key).arg(value)
312 }
313
314 fn incr<K: ToRedisArgs, V: ToRedisArgs>(key: K, delta: V) {
317 cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
318 "INCRBYFLOAT"
319 } else {
320 "INCRBY"
321 }).arg(key).arg(delta)
322 }
323
324 fn decr<K: ToRedisArgs, V: ToRedisArgs>(key: K, delta: V) {
326 cmd("DECRBY").arg(key).arg(delta)
327 }
328
329 fn setbit<K: ToRedisArgs>(key: K, offset: usize, value: bool) {
331 cmd("SETBIT").arg(key).arg(offset).arg(i32::from(value))
332 }
333
334 fn getbit<K: ToRedisArgs>(key: K, offset: usize) {
336 cmd("GETBIT").arg(key).arg(offset)
337 }
338
339 fn bitcount<K: ToRedisArgs>(key: K) {
341 cmd("BITCOUNT").arg(key)
342 }
343
344 fn bitcount_range<K: ToRedisArgs>(key: K, start: usize, end: usize) {
346 cmd("BITCOUNT").arg(key).arg(start).arg(end)
347 }
348
349 fn bit_and<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
352 cmd("BITOP").arg("AND").arg(dstkey).arg(srckeys)
353 }
354
355 fn bit_or<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
358 cmd("BITOP").arg("OR").arg(dstkey).arg(srckeys)
359 }
360
361 fn bit_xor<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
364 cmd("BITOP").arg("XOR").arg(dstkey).arg(srckeys)
365 }
366
367 fn bit_not<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckey: S) {
370 cmd("BITOP").arg("NOT").arg(dstkey).arg(srckey)
371 }
372
373 fn strlen<K: ToRedisArgs>(key: K) {
375 cmd("STRLEN").arg(key)
376 }
377
378 fn hget<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
382 cmd(if field.num_of_args() <= 1 { "HGET" } else { "HMGET" }).arg(key).arg(field)
383 }
384
385 fn hdel<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
387 cmd("HDEL").arg(key).arg(field)
388 }
389
390 fn hset<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
392 cmd("HSET").arg(key).arg(field).arg(value)
393 }
394
395 fn hset_nx<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
397 cmd("HSETNX").arg(key).arg(field).arg(value)
398 }
399
400 fn hset_multiple<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, items: &'a [(F, V)]) {
402 cmd("HMSET").arg(key).arg(items)
403 }
404
405 fn hincr<K: ToRedisArgs, F: ToRedisArgs, D: ToRedisArgs>(key: K, field: F, delta: D) {
407 cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
408 "HINCRBYFLOAT"
409 } else {
410 "HINCRBY"
411 }).arg(key).arg(field).arg(delta)
412 }
413
414 fn hexists<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
416 cmd("HEXISTS").arg(key).arg(field)
417 }
418
419 fn httl<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
421 cmd("HTTL").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
422 }
423
424 fn hpttl<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
426 cmd("HPTTL").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
427 }
428
429 fn hexpire<K: ToRedisArgs, F: ToRedisArgs>(key: K, seconds: i64, opt: ExpireOption, fields: F) {
431 cmd("HEXPIRE").arg(key).arg(seconds).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
432 }
433
434 fn hexpire_at<K: ToRedisArgs, F: ToRedisArgs>(key: K, ts: i64, opt: ExpireOption, fields: F) {
436 cmd("HEXPIREAT").arg(key).arg(ts).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
437 }
438
439 fn hexpire_time<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
441 cmd("HEXPIRETIME").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
442 }
443
444 fn hpersist<K: ToRedisArgs, F :ToRedisArgs>(key: K, fields: F) {
446 cmd("HPERSIST").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
447 }
448
449 fn hpexpire<K: ToRedisArgs, F: ToRedisArgs>(key: K, milliseconds: i64, opt: ExpireOption, fields: F) {
451 cmd("HPEXPIRE").arg(key).arg(milliseconds).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
452 }
453
454 fn hpexpire_at<K: ToRedisArgs, F: ToRedisArgs>(key: K, ts: i64, opt: ExpireOption, fields: F) {
456 cmd("HPEXPIREAT").arg(key).arg(ts).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
457 }
458
459 fn hpexpire_time<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
461 cmd("HPEXPIRETIME").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
462 }
463
464 fn hkeys<K: ToRedisArgs>(key: K) {
466 cmd("HKEYS").arg(key)
467 }
468
469 fn hvals<K: ToRedisArgs>(key: K) {
471 cmd("HVALS").arg(key)
472 }
473
474 fn hgetall<K: ToRedisArgs>(key: K) {
476 cmd("HGETALL").arg(key)
477 }
478
479 fn hlen<K: ToRedisArgs>(key: K) {
481 cmd("HLEN").arg(key)
482 }
483
484 fn blmove<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, src_dir: Direction, dst_dir: Direction, timeout: f64) {
489 cmd("BLMOVE").arg(srckey).arg(dstkey).arg(src_dir).arg(dst_dir).arg(timeout)
490 }
491
492 fn blmpop<K: ToRedisArgs>(timeout: f64, numkeys: usize, key: K, dir: Direction, count: usize){
495 cmd("BLMPOP").arg(timeout).arg(numkeys).arg(key).arg(dir).arg("COUNT").arg(count)
496 }
497
498 fn blpop<K: ToRedisArgs>(key: K, timeout: f64) {
500 cmd("BLPOP").arg(key).arg(timeout)
501 }
502
503 fn brpop<K: ToRedisArgs>(key: K, timeout: f64) {
505 cmd("BRPOP").arg(key).arg(timeout)
506 }
507
508 fn brpoplpush<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, timeout: f64) {
511 cmd("BRPOPLPUSH").arg(srckey).arg(dstkey).arg(timeout)
512 }
513
514 fn lindex<K: ToRedisArgs>(key: K, index: isize) {
516 cmd("LINDEX").arg(key).arg(index)
517 }
518
519 fn linsert_before<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
521 key: K, pivot: P, value: V) {
522 cmd("LINSERT").arg(key).arg("BEFORE").arg(pivot).arg(value)
523 }
524
525 fn linsert_after<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
527 key: K, pivot: P, value: V) {
528 cmd("LINSERT").arg(key).arg("AFTER").arg(pivot).arg(value)
529 }
530
531 fn llen<K: ToRedisArgs>(key: K) {
533 cmd("LLEN").arg(key)
534 }
535
536 fn lmove<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, src_dir: Direction, dst_dir: Direction) {
538 cmd("LMOVE").arg(srckey).arg(dstkey).arg(src_dir).arg(dst_dir)
539 }
540
541 fn lmpop<K: ToRedisArgs>( numkeys: usize, key: K, dir: Direction, count: usize) {
544 cmd("LMPOP").arg(numkeys).arg(key).arg(dir).arg("COUNT").arg(count)
545 }
546
547 fn lpop<K: ToRedisArgs>(key: K, count: Option<core::num::NonZeroUsize>) {
551 cmd("LPOP").arg(key).arg(count)
552 }
553
554 fn lpos<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, options: LposOptions) {
556 cmd("LPOS").arg(key).arg(value).arg(options)
557 }
558
559 fn lpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
561 cmd("LPUSH").arg(key).arg(value)
562 }
563
564 fn lpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
567 cmd("LPUSHX").arg(key).arg(value)
568 }
569
570 fn lrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
572 cmd("LRANGE").arg(key).arg(start).arg(stop)
573 }
574
575 fn lrem<K: ToRedisArgs, V: ToRedisArgs>(key: K, count: isize, value: V) {
578 cmd("LREM").arg(key).arg(count).arg(value)
579 }
580
581 fn ltrim<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
584 cmd("LTRIM").arg(key).arg(start).arg(stop)
585 }
586
587 fn lset<K: ToRedisArgs, V: ToRedisArgs>(key: K, index: isize, value: V) {
589 cmd("LSET").arg(key).arg(index).arg(value)
590 }
591
592 fn ping<>() {
594 &mut cmd("PING")
595 }
596
597 fn ping_message<K: ToRedisArgs>(message: K) {
599 cmd("PING").arg(message)
600 }
601
602 fn rpop<K: ToRedisArgs>(key: K, count: Option<core::num::NonZeroUsize>) {
606 cmd("RPOP").arg(key).arg(count)
607 }
608
609 fn rpoplpush<K: ToRedisArgs, D: ToRedisArgs>(key: K, dstkey: D) {
611 cmd("RPOPLPUSH").arg(key).arg(dstkey)
612 }
613
614 fn rpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
616 cmd("RPUSH").arg(key).arg(value)
617 }
618
619 fn rpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
622 cmd("RPUSHX").arg(key).arg(value)
623 }
624
625 fn sadd<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
629 cmd("SADD").arg(key).arg(member)
630 }
631
632 fn scard<K: ToRedisArgs>(key: K) {
634 cmd("SCARD").arg(key)
635 }
636
637 fn sdiff<K: ToRedisArgs>(keys: K) {
639 cmd("SDIFF").arg(keys)
640 }
641
642 fn sdiffstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
644 cmd("SDIFFSTORE").arg(dstkey).arg(keys)
645 }
646
647 fn sinter<K: ToRedisArgs>(keys: K) {
649 cmd("SINTER").arg(keys)
650 }
651
652 fn sinterstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
654 cmd("SINTERSTORE").arg(dstkey).arg(keys)
655 }
656
657 fn sismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
659 cmd("SISMEMBER").arg(key).arg(member)
660 }
661
662 fn smismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
664 cmd("SMISMEMBER").arg(key).arg(members)
665 }
666
667 fn smembers<K: ToRedisArgs>(key: K) {
669 cmd("SMEMBERS").arg(key)
670 }
671
672 fn smove<S: ToRedisArgs, D: ToRedisArgs, M: ToRedisArgs>(srckey: S, dstkey: D, member: M) {
674 cmd("SMOVE").arg(srckey).arg(dstkey).arg(member)
675 }
676
677 fn spop<K: ToRedisArgs>(key: K) {
679 cmd("SPOP").arg(key)
680 }
681
682 fn srandmember<K: ToRedisArgs>(key: K) {
684 cmd("SRANDMEMBER").arg(key)
685 }
686
687 fn srandmember_multiple<K: ToRedisArgs>(key: K, count: usize) {
689 cmd("SRANDMEMBER").arg(key).arg(count)
690 }
691
692 fn srem<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
694 cmd("SREM").arg(key).arg(member)
695 }
696
697 fn sunion<K: ToRedisArgs>(keys: K) {
699 cmd("SUNION").arg(keys)
700 }
701
702 fn sunionstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
704 cmd("SUNIONSTORE").arg(dstkey).arg(keys)
705 }
706
707 fn zadd<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, member: M, score: S) {
711 cmd("ZADD").arg(key).arg(score).arg(member)
712 }
713
714 fn zadd_multiple<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, items: &'a [(S, M)]) {
716 cmd("ZADD").arg(key).arg(items)
717 }
718
719 fn zcard<K: ToRedisArgs>(key: K) {
721 cmd("ZCARD").arg(key)
722 }
723
724 fn zcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
726 cmd("ZCOUNT").arg(key).arg(min).arg(max)
727 }
728
729 fn zincr<K: ToRedisArgs, M: ToRedisArgs, D: ToRedisArgs>(key: K, member: M, delta: D) {
732 cmd("ZINCRBY").arg(key).arg(delta).arg(member)
733 }
734
735 fn zinterstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
738 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys)
739 }
740
741 fn zinterstore_min<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
744 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN")
745 }
746
747 fn zinterstore_max<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
750 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX")
751 }
752
753 fn zinterstore_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
757 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
758 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("WEIGHTS").arg(weights)
759 }
760
761 fn zinterstore_min_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
765 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
766 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN").arg("WEIGHTS").arg(weights)
767 }
768
769 fn zinterstore_max_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
773 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
774 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX").arg("WEIGHTS").arg(weights)
775 }
776
777 fn zlexcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
779 cmd("ZLEXCOUNT").arg(key).arg(min).arg(max)
780 }
781
782 fn bzpopmax<K: ToRedisArgs>(key: K, timeout: f64) {
785 cmd("BZPOPMAX").arg(key).arg(timeout)
786 }
787
788 fn zpopmax<K: ToRedisArgs>(key: K, count: isize) {
790 cmd("ZPOPMAX").arg(key).arg(count)
791 }
792
793 fn bzpopmin<K: ToRedisArgs>(key: K, timeout: f64) {
796 cmd("BZPOPMIN").arg(key).arg(timeout)
797 }
798
799 fn zpopmin<K: ToRedisArgs>(key: K, count: isize) {
801 cmd("ZPOPMIN").arg(key).arg(count)
802 }
803
804 fn bzmpop_max<K: ToRedisArgs>(timeout: f64, keys: K, count: isize) {
808 cmd("BZMPOP").arg(timeout).arg(keys.num_of_args()).arg(keys).arg("MAX").arg("COUNT").arg(count)
809 }
810
811 fn zmpop_max<K: ToRedisArgs>(keys: K, count: isize) {
814 cmd("ZMPOP").arg(keys.num_of_args()).arg(keys).arg("MAX").arg("COUNT").arg(count)
815 }
816
817 fn bzmpop_min<K: ToRedisArgs>(timeout: f64, keys: K, count: isize) {
821 cmd("BZMPOP").arg(timeout).arg(keys.num_of_args()).arg(keys).arg("MIN").arg("COUNT").arg(count)
822 }
823
824 fn zmpop_min<K: ToRedisArgs>(keys: K, count: isize) {
827 cmd("ZMPOP").arg(keys.num_of_args()).arg(keys).arg("MIN").arg("COUNT").arg(count)
828 }
829
830 fn zrandmember<K: ToRedisArgs>(key: K, count: Option<isize>) {
832 cmd("ZRANDMEMBER").arg(key).arg(count)
833 }
834
835 fn zrandmember_withscores<K: ToRedisArgs>(key: K, count: isize) {
837 cmd("ZRANDMEMBER").arg(key).arg(count).arg("WITHSCORES")
838 }
839
840 fn zrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
842 cmd("ZRANGE").arg(key).arg(start).arg(stop)
843 }
844
845 fn zrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
847 cmd("ZRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
848 }
849
850 fn zrangebylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
852 cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max)
853 }
854
855 fn zrangebylex_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(
858 key: K, min: M, max: MM, offset: isize, count: isize) {
859 cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
860 }
861
862 fn zrevrangebylex<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
864 cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min)
865 }
866
867 fn zrevrangebylex_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(
870 key: K, max: MM, min: M, offset: isize, count: isize) {
871 cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
872 }
873
874 fn zrangebyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
876 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max)
877 }
878
879 fn zrangebyscore_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
881 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
882 }
883
884 fn zrangebyscore_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
886 (key: K, min: M, max: MM, offset: isize, count: isize) {
887 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
888 }
889
890 fn zrangebyscore_limit_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
892 (key: K, min: M, max: MM, offset: isize, count: isize) {
893 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
894 .arg("LIMIT").arg(offset).arg(count)
895 }
896
897 fn zrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
899 cmd("ZRANK").arg(key).arg(member)
900 }
901
902 fn zrem<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
904 cmd("ZREM").arg(key).arg(members)
905 }
906
907 fn zrembylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
909 cmd("ZREMRANGEBYLEX").arg(key).arg(min).arg(max)
910 }
911
912 fn zremrangebyrank<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
914 cmd("ZREMRANGEBYRANK").arg(key).arg(start).arg(stop)
915 }
916
917 fn zrembyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
919 cmd("ZREMRANGEBYSCORE").arg(key).arg(min).arg(max)
920 }
921
922 fn zrevrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
925 cmd("ZREVRANGE").arg(key).arg(start).arg(stop)
926 }
927
928 fn zrevrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
931 cmd("ZREVRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
932 }
933
934 fn zrevrangebyscore<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
936 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min)
937 }
938
939 fn zrevrangebyscore_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
941 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
942 }
943
944 fn zrevrangebyscore_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
946 (key: K, max: MM, min: M, offset: isize, count: isize) {
947 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
948 }
949
950 fn zrevrangebyscore_limit_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
952 (key: K, max: MM, min: M, offset: isize, count: isize) {
953 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
954 .arg("LIMIT").arg(offset).arg(count)
955 }
956
957 fn zrevrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
959 cmd("ZREVRANK").arg(key).arg(member)
960 }
961
962 fn zscore<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
964 cmd("ZSCORE").arg(key).arg(member)
965 }
966
967 fn zscore_multiple<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: &'a [M]) {
969 cmd("ZMSCORE").arg(key).arg(members)
970 }
971
972 fn zunionstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
975 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys)
976 }
977
978 fn zunionstore_min<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
981 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN")
982 }
983
984 fn zunionstore_max<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
987 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX")
988 }
989
990 fn zunionstore_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
994 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
995 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("WEIGHTS").arg(weights)
996 }
997
998 fn zunionstore_min_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
1002 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
1003 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN").arg("WEIGHTS").arg(weights)
1004 }
1005
1006 fn zunionstore_max_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
1010 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
1011 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX").arg("WEIGHTS").arg(weights)
1012 }
1013
1014 fn pfadd<K: ToRedisArgs, E: ToRedisArgs>(key: K, element: E) {
1018 cmd("PFADD").arg(key).arg(element)
1019 }
1020
1021 fn pfcount<K: ToRedisArgs>(key: K) {
1024 cmd("PFCOUNT").arg(key)
1025 }
1026
1027 fn pfmerge<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
1029 cmd("PFMERGE").arg(dstkey).arg(srckeys)
1030 }
1031
1032 fn publish<K: ToRedisArgs, E: ToRedisArgs>(channel: K, message: E) {
1034 cmd("PUBLISH").arg(channel).arg(message)
1035 }
1036
1037 fn spublish<K: ToRedisArgs, E: ToRedisArgs>(channel: K, message: E) {
1039 cmd("SPUBLISH").arg(channel).arg(message)
1040 }
1041
1042 fn object_encoding<K: ToRedisArgs>(key: K) {
1046 cmd("OBJECT").arg("ENCODING").arg(key)
1047 }
1048
1049 fn object_idletime<K: ToRedisArgs>(key: K) {
1051 cmd("OBJECT").arg("IDLETIME").arg(key)
1052 }
1053
1054 fn object_freq<K: ToRedisArgs>(key: K) {
1056 cmd("OBJECT").arg("FREQ").arg(key)
1057 }
1058
1059 fn object_refcount<K: ToRedisArgs>(key: K) {
1061 cmd("OBJECT").arg("REFCOUNT").arg(key)
1062 }
1063
1064 fn client_getname<>() {
1066 cmd("CLIENT").arg("GETNAME")
1067 }
1068
1069 fn client_id<>() {
1071 cmd("CLIENT").arg("ID")
1072 }
1073
1074 fn client_setname<K: ToRedisArgs>(connection_name: K) {
1076 cmd("CLIENT").arg("SETNAME").arg(connection_name)
1077 }
1078
1079 #[cfg(feature = "acl")]
1085 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1086 fn acl_load<>() {
1087 cmd("ACL").arg("LOAD")
1088 }
1089
1090 #[cfg(feature = "acl")]
1094 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1095 fn acl_save<>() {
1096 cmd("ACL").arg("SAVE")
1097 }
1098
1099 #[cfg(feature = "acl")]
1101 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1102 fn acl_list<>() {
1103 cmd("ACL").arg("LIST")
1104 }
1105
1106 #[cfg(feature = "acl")]
1109 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1110 fn acl_users<>() {
1111 cmd("ACL").arg("USERS")
1112 }
1113
1114 #[cfg(feature = "acl")]
1116 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1117 fn acl_getuser<K: ToRedisArgs>(username: K) {
1118 cmd("ACL").arg("GETUSER").arg(username)
1119 }
1120
1121 #[cfg(feature = "acl")]
1123 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1124 fn acl_setuser<K: ToRedisArgs>(username: K) {
1125 cmd("ACL").arg("SETUSER").arg(username)
1126 }
1127
1128 #[cfg(feature = "acl")]
1131 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1132 fn acl_setuser_rules<K: ToRedisArgs>(username: K, rules: &'a [acl::Rule]) {
1133 cmd("ACL").arg("SETUSER").arg(username).arg(rules)
1134 }
1135
1136 #[cfg(feature = "acl")]
1139 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1140 fn acl_deluser<K: ToRedisArgs>(usernames: &'a [K]) {
1141 cmd("ACL").arg("DELUSER").arg(usernames)
1142 }
1143
1144 #[cfg(feature = "acl")]
1146 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1147 fn acl_dryrun<K: ToRedisArgs, C: ToRedisArgs, A: ToRedisArgs>(username: K, command: C, args: A) {
1148 cmd("ACL").arg("DRYRUN").arg(username).arg(command).arg(args)
1149 }
1150
1151 #[cfg(feature = "acl")]
1153 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1154 fn acl_cat<>() {
1155 cmd("ACL").arg("CAT")
1156 }
1157
1158 #[cfg(feature = "acl")]
1160 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1161 fn acl_cat_categoryname<K: ToRedisArgs>(categoryname: K) {
1162 cmd("ACL").arg("CAT").arg(categoryname)
1163 }
1164
1165 #[cfg(feature = "acl")]
1167 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1168 fn acl_genpass<>() {
1169 cmd("ACL").arg("GENPASS")
1170 }
1171
1172 #[cfg(feature = "acl")]
1174 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1175 fn acl_genpass_bits<>(bits: isize) {
1176 cmd("ACL").arg("GENPASS").arg(bits)
1177 }
1178
1179 #[cfg(feature = "acl")]
1181 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1182 fn acl_whoami<>() {
1183 cmd("ACL").arg("WHOAMI")
1184 }
1185
1186 #[cfg(feature = "acl")]
1188 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1189 fn acl_log<>(count: isize) {
1190 cmd("ACL").arg("LOG").arg(count)
1191
1192 }
1193
1194 #[cfg(feature = "acl")]
1196 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1197 fn acl_log_reset<>() {
1198 cmd("ACL").arg("LOG").arg("RESET")
1199 }
1200
1201 #[cfg(feature = "acl")]
1203 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1204 fn acl_help<>() {
1205 cmd("ACL").arg("HELP")
1206 }
1207
1208 #[cfg(feature = "geospatial")]
1246 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1247 fn geo_add<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1248 cmd("GEOADD").arg(key).arg(members)
1249 }
1250
1251 #[cfg(feature = "geospatial")]
1283 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1284 fn geo_dist<K: ToRedisArgs, M1: ToRedisArgs, M2: ToRedisArgs>(
1285 key: K,
1286 member1: M1,
1287 member2: M2,
1288 unit: geo::Unit
1289 ) {
1290 cmd("GEODIST")
1291 .arg(key)
1292 .arg(member1)
1293 .arg(member2)
1294 .arg(unit)
1295 }
1296
1297 #[cfg(feature = "geospatial")]
1317 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1318 fn geo_hash<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1319 cmd("GEOHASH").arg(key).arg(members)
1320 }
1321
1322 #[cfg(feature = "geospatial")]
1346 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1347 fn geo_pos<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1348 cmd("GEOPOS").arg(key).arg(members)
1349 }
1350
1351 #[cfg(feature = "geospatial")]
1371 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1372 fn geo_radius<K: ToRedisArgs>(
1373 key: K,
1374 longitude: f64,
1375 latitude: f64,
1376 radius: f64,
1377 unit: geo::Unit,
1378 options: geo::RadiusOptions
1379 ) {
1380 cmd("GEORADIUS")
1381 .arg(key)
1382 .arg(longitude)
1383 .arg(latitude)
1384 .arg(radius)
1385 .arg(unit)
1386 .arg(options)
1387 }
1388
1389 #[cfg(feature = "geospatial")]
1392 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1393 fn geo_radius_by_member<K: ToRedisArgs, M: ToRedisArgs>(
1394 key: K,
1395 member: M,
1396 radius: f64,
1397 unit: geo::Unit,
1398 options: geo::RadiusOptions
1399 ) {
1400 cmd("GEORADIUSBYMEMBER")
1401 .arg(key)
1402 .arg(member)
1403 .arg(radius)
1404 .arg(unit)
1405 .arg(options)
1406 }
1407
1408 #[cfg(feature = "streams")]
1418 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1419 fn xack<K: ToRedisArgs, G: ToRedisArgs, I: ToRedisArgs>(
1420 key: K,
1421 group: G,
1422 ids: &'a [I]) {
1423 cmd("XACK")
1424 .arg(key)
1425 .arg(group)
1426 .arg(ids)
1427 }
1428
1429
1430 #[cfg(feature = "streams")]
1436 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1437 fn xadd<K: ToRedisArgs, ID: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(
1438 key: K,
1439 id: ID,
1440 items: &'a [(F, V)]
1441 ) {
1442 cmd("XADD").arg(key).arg(id).arg(items)
1443 }
1444
1445
1446 #[cfg(feature = "streams")]
1453 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1454 fn xadd_map<K: ToRedisArgs, ID: ToRedisArgs, BTM: ToRedisArgs>(
1455 key: K,
1456 id: ID,
1457 map: BTM
1458 ) {
1459 cmd("XADD").arg(key).arg(id).arg(map)
1460 }
1461
1462
1463 #[cfg(feature = "streams")]
1481 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1482 fn xadd_options<
1483 K: ToRedisArgs, ID: ToRedisArgs, I: ToRedisArgs
1484 >(
1485 key: K,
1486 id: ID,
1487 items: I,
1488 options: &'a streams::StreamAddOptions
1489 ) {
1490 cmd("XADD")
1491 .arg(key)
1492 .arg(options)
1493 .arg(id)
1494 .arg(items)
1495 }
1496
1497
1498 #[cfg(feature = "streams")]
1504 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1505 fn xadd_maxlen<
1506 K: ToRedisArgs,
1507 ID: ToRedisArgs,
1508 F: ToRedisArgs,
1509 V: ToRedisArgs
1510 >(
1511 key: K,
1512 maxlen: streams::StreamMaxlen,
1513 id: ID,
1514 items: &'a [(F, V)]
1515 ) {
1516 cmd("XADD")
1517 .arg(key)
1518 .arg(maxlen)
1519 .arg(id)
1520 .arg(items)
1521 }
1522
1523
1524 #[cfg(feature = "streams")]
1530 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1531 fn xadd_maxlen_map<K: ToRedisArgs, ID: ToRedisArgs, BTM: ToRedisArgs>(
1532 key: K,
1533 maxlen: streams::StreamMaxlen,
1534 id: ID,
1535 map: BTM
1536 ) {
1537 cmd("XADD")
1538 .arg(key)
1539 .arg(maxlen)
1540 .arg(id)
1541 .arg(map)
1542 }
1543
1544 #[cfg(feature = "streams")]
1560 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1561 fn xautoclaim_options<
1562 K: ToRedisArgs,
1563 G: ToRedisArgs,
1564 C: ToRedisArgs,
1565 MIT: ToRedisArgs,
1566 S: ToRedisArgs
1567 >(
1568 key: K,
1569 group: G,
1570 consumer: C,
1571 min_idle_time: MIT,
1572 start: S,
1573 options: streams::StreamAutoClaimOptions
1574 ) {
1575 cmd("XAUTOCLAIM")
1576 .arg(key)
1577 .arg(group)
1578 .arg(consumer)
1579 .arg(min_idle_time)
1580 .arg(start)
1581 .arg(options)
1582 }
1583
1584 #[cfg(feature = "streams")]
1594 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1595 fn xclaim<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs, MIT: ToRedisArgs, ID: ToRedisArgs>(
1596 key: K,
1597 group: G,
1598 consumer: C,
1599 min_idle_time: MIT,
1600 ids: &'a [ID]
1601 ) {
1602 cmd("XCLAIM")
1603 .arg(key)
1604 .arg(group)
1605 .arg(consumer)
1606 .arg(min_idle_time)
1607 .arg(ids)
1608 }
1609
1610 #[cfg(feature = "streams")]
1644 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1645 fn xclaim_options<
1646 K: ToRedisArgs,
1647 G: ToRedisArgs,
1648 C: ToRedisArgs,
1649 MIT: ToRedisArgs,
1650 ID: ToRedisArgs
1651 >(
1652 key: K,
1653 group: G,
1654 consumer: C,
1655 min_idle_time: MIT,
1656 ids: &'a [ID],
1657 options: streams::StreamClaimOptions
1658 ) {
1659 cmd("XCLAIM")
1660 .arg(key)
1661 .arg(group)
1662 .arg(consumer)
1663 .arg(min_idle_time)
1664 .arg(ids)
1665 .arg(options)
1666 }
1667
1668
1669 #[cfg(feature = "streams")]
1675 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1676 fn xdel<K: ToRedisArgs, ID: ToRedisArgs>(
1677 key: K,
1678 ids: &'a [ID]
1679 ) {
1680 cmd("XDEL").arg(key).arg(ids)
1681 }
1682
1683
1684 #[cfg(feature = "streams")]
1693 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1694 fn xgroup_create<K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs>(
1695 key: K,
1696 group: G,
1697 id: ID
1698 ) {
1699 cmd("XGROUP")
1700 .arg("CREATE")
1701 .arg(key)
1702 .arg(group)
1703 .arg(id)
1704 }
1705
1706 #[cfg(feature = "streams")]
1716 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1717 fn xgroup_createconsumer<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs>(
1718 key: K,
1719 group: G,
1720 consumer: C
1721 ) {
1722 cmd("XGROUP")
1723 .arg("CREATECONSUMER")
1724 .arg(key)
1725 .arg(group)
1726 .arg(consumer)
1727 }
1728
1729 #[cfg(feature = "streams")]
1736 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1737 fn xgroup_create_mkstream<
1738 K: ToRedisArgs,
1739 G: ToRedisArgs,
1740 ID: ToRedisArgs
1741 >(
1742 key: K,
1743 group: G,
1744 id: ID
1745 ) {
1746 cmd("XGROUP")
1747 .arg("CREATE")
1748 .arg(key)
1749 .arg(group)
1750 .arg(id)
1751 .arg("MKSTREAM")
1752 }
1753
1754
1755 #[cfg(feature = "streams")]
1762 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1763 fn xgroup_setid<K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs>(
1764 key: K,
1765 group: G,
1766 id: ID
1767 ) {
1768 cmd("XGROUP")
1769 .arg("SETID")
1770 .arg(key)
1771 .arg(group)
1772 .arg(id)
1773 }
1774
1775
1776 #[cfg(feature = "streams")]
1782 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1783 fn xgroup_destroy<K: ToRedisArgs, G: ToRedisArgs>(
1784 key: K,
1785 group: G
1786 ) {
1787 cmd("XGROUP").arg("DESTROY").arg(key).arg(group)
1788 }
1789
1790 #[cfg(feature = "streams")]
1797 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1798 fn xgroup_delconsumer<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs>(
1799 key: K,
1800 group: G,
1801 consumer: C
1802 ) {
1803 cmd("XGROUP")
1804 .arg("DELCONSUMER")
1805 .arg(key)
1806 .arg(group)
1807 .arg(consumer)
1808 }
1809
1810
1811 #[cfg(feature = "streams")]
1822 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1823 fn xinfo_consumers<K: ToRedisArgs, G: ToRedisArgs>(
1824 key: K,
1825 group: G
1826 ) {
1827 cmd("XINFO")
1828 .arg("CONSUMERS")
1829 .arg(key)
1830 .arg(group)
1831 }
1832
1833
1834 #[cfg(feature = "streams")]
1844 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1845 fn xinfo_groups<K: ToRedisArgs>(key: K) {
1846 cmd("XINFO").arg("GROUPS").arg(key)
1847 }
1848
1849
1850 #[cfg(feature = "streams")]
1861 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1862 fn xinfo_stream<K: ToRedisArgs>(key: K) {
1863 cmd("XINFO").arg("STREAM").arg(key)
1864 }
1865
1866 #[cfg(feature = "streams")]
1872 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1873 fn xlen<K: ToRedisArgs>(key: K) {
1874 cmd("XLEN").arg(key)
1875 }
1876
1877
1878 #[cfg(feature = "streams")]
1893 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1894 fn xpending<K: ToRedisArgs, G: ToRedisArgs>(
1895 key: K,
1896 group: G
1897 ) {
1898 cmd("XPENDING").arg(key).arg(group)
1899 }
1900
1901
1902 #[cfg(feature = "streams")]
1914 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1915 fn xpending_count<
1916 K: ToRedisArgs,
1917 G: ToRedisArgs,
1918 S: ToRedisArgs,
1919 E: ToRedisArgs,
1920 C: ToRedisArgs
1921 >(
1922 key: K,
1923 group: G,
1924 start: S,
1925 end: E,
1926 count: C
1927 ) {
1928 cmd("XPENDING")
1929 .arg(key)
1930 .arg(group)
1931 .arg(start)
1932 .arg(end)
1933 .arg(count)
1934 }
1935
1936
1937 #[cfg(feature = "streams")]
1948 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1949 fn xpending_consumer_count<
1950 K: ToRedisArgs,
1951 G: ToRedisArgs,
1952 S: ToRedisArgs,
1953 E: ToRedisArgs,
1954 C: ToRedisArgs,
1955 CN: ToRedisArgs
1956 >(
1957 key: K,
1958 group: G,
1959 start: S,
1960 end: E,
1961 count: C,
1962 consumer: CN
1963 ) {
1964 cmd("XPENDING")
1965 .arg(key)
1966 .arg(group)
1967 .arg(start)
1968 .arg(end)
1969 .arg(count)
1970 .arg(consumer)
1971 }
1972
1973 #[cfg(feature = "streams")]
1985 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1986 fn xrange<K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs>(
1987 key: K,
1988 start: S,
1989 end: E
1990 ) {
1991 cmd("XRANGE").arg(key).arg(start).arg(end)
1992 }
1993
1994
1995 #[cfg(feature = "streams")]
2002 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2003 fn xrange_all<K: ToRedisArgs>(key: K) {
2004 cmd("XRANGE").arg(key).arg("-").arg("+")
2005 }
2006
2007
2008 #[cfg(feature = "streams")]
2014 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2015 fn xrange_count<K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs, C: ToRedisArgs>(
2016 key: K,
2017 start: S,
2018 end: E,
2019 count: C
2020 ) {
2021 cmd("XRANGE")
2022 .arg(key)
2023 .arg(start)
2024 .arg(end)
2025 .arg("COUNT")
2026 .arg(count)
2027 }
2028
2029
2030 #[cfg(feature = "streams")]
2039 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2040 fn xread<K: ToRedisArgs, ID: ToRedisArgs>(
2041 keys: &'a [K],
2042 ids: &'a [ID]
2043 ) {
2044 cmd("XREAD").arg("STREAMS").arg(keys).arg(ids)
2045 }
2046
2047 #[cfg(feature = "streams")]
2084 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2085 fn xread_options<K: ToRedisArgs, ID: ToRedisArgs>(
2086 keys: &'a [K],
2087 ids: &'a [ID],
2088 options: &'a streams::StreamReadOptions
2089 ) {
2090 cmd(if options.read_only() {
2091 "XREAD"
2092 } else {
2093 "XREADGROUP"
2094 })
2095 .arg(options)
2096 .arg("STREAMS")
2097 .arg(keys)
2098 .arg(ids)
2099 }
2100
2101 #[cfg(feature = "streams")]
2108 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2109 fn xrevrange<K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs>(
2110 key: K,
2111 end: E,
2112 start: S
2113 ) {
2114 cmd("XREVRANGE").arg(key).arg(end).arg(start)
2115 }
2116
2117 fn xrevrange_all<K: ToRedisArgs>(key: K) {
2124 cmd("XREVRANGE").arg(key).arg("+").arg("-")
2125 }
2126
2127 #[cfg(feature = "streams")]
2134 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2135 fn xrevrange_count<K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs, C: ToRedisArgs>(
2136 key: K,
2137 end: E,
2138 start: S,
2139 count: C
2140 ) {
2141 cmd("XREVRANGE")
2142 .arg(key)
2143 .arg(end)
2144 .arg(start)
2145 .arg("COUNT")
2146 .arg(count)
2147 }
2148
2149 #[cfg(feature = "streams")]
2155 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2156 fn xtrim<K: ToRedisArgs>(
2157 key: K,
2158 maxlen: streams::StreamMaxlen
2159 ) {
2160 cmd("XTRIM").arg(key).arg(maxlen)
2161 }
2162
2163 #[cfg(feature = "streams")]
2169 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2170 fn xtrim_options<K: ToRedisArgs>(
2171 key: K,
2172 options: &'a streams::StreamTrimOptions
2173 ) {
2174 cmd("XTRIM").arg(key).arg(options)
2175 }
2176
2177 #[cfg_attr(feature = "script", doc = r##"
2185
2186# Examples:
2187
2188```rust,no_run
2189# fn do_something() -> redis::RedisResult<()> {
2190# let client = redis::Client::open("redis://127.0.0.1/").unwrap();
2191# let mut con = client.get_connection().unwrap();
2192let script = redis::Script::new(r"
2193 return tonumber(ARGV[1]) + tonumber(ARGV[2]);
2194");
2195script.prepare_invoke().load(&mut con)?;
2196let (a, b): (isize, isize) = redis::pipe()
2197 .invoke_script(script.arg(1).arg(2))
2198 .invoke_script(script.arg(2).arg(3))
2199 .query(&mut con)?;
2200
2201assert_eq!(a, 3);
2202assert_eq!(b, 5);
2203# Ok(()) }
2204```
2205"##)]
2206 #[cfg(feature = "script")]
2207 #[cfg_attr(docsrs, doc(cfg(feature = "script")))]
2208 fn invoke_script<>(invocation: &'a crate::ScriptInvocation<'a>) {
2209 &mut invocation.eval_cmd()
2210 }
2211
2212 fn flushall<>() {
2225 &mut cmd("FLUSHALL")
2226 }
2227
2228 fn flushall_options<>(options: &'a FlushAllOptions) {
2234 cmd("FLUSHALL").arg(options)
2235 }
2236
2237 fn flushdb<>() {
2248 &mut cmd("FLUSHDB")
2249 }
2250
2251 fn flushdb_options<>(options: &'a FlushDbOptions) {
2257 cmd("FLUSHDB").arg(options)
2258 }
2259}
2260
2261pub enum ControlFlow<U> {
2265 Continue,
2267 Break(U),
2269}
2270
2271pub trait PubSubCommands: Sized {
2306 fn subscribe<C, F, U>(&mut self, _: C, _: F) -> RedisResult<U>
2313 where
2314 F: FnMut(Msg) -> ControlFlow<U>,
2315 C: ToRedisArgs;
2316
2317 fn psubscribe<P, F, U>(&mut self, _: P, _: F) -> RedisResult<U>
2324 where
2325 F: FnMut(Msg) -> ControlFlow<U>,
2326 P: ToRedisArgs;
2327}
2328
2329impl<T> Commands for T where T: ConnectionLike {}
2330
2331#[cfg(feature = "aio")]
2332impl<T> AsyncCommands for T where T: crate::aio::ConnectionLike + Send + Sync + Sized {}
2333
2334impl PubSubCommands for Connection {
2335 fn subscribe<C, F, U>(&mut self, channels: C, mut func: F) -> RedisResult<U>
2336 where
2337 F: FnMut(Msg) -> ControlFlow<U>,
2338 C: ToRedisArgs,
2339 {
2340 let mut pubsub = self.as_pubsub();
2341 pubsub.subscribe(channels)?;
2342
2343 loop {
2344 let msg = pubsub.get_message()?;
2345 match func(msg) {
2346 ControlFlow::Continue => continue,
2347 ControlFlow::Break(value) => return Ok(value),
2348 }
2349 }
2350 }
2351
2352 fn psubscribe<P, F, U>(&mut self, patterns: P, mut func: F) -> RedisResult<U>
2353 where
2354 F: FnMut(Msg) -> ControlFlow<U>,
2355 P: ToRedisArgs,
2356 {
2357 let mut pubsub = self.as_pubsub();
2358 pubsub.psubscribe(patterns)?;
2359
2360 loop {
2361 let msg = pubsub.get_message()?;
2362 match func(msg) {
2363 ControlFlow::Continue => continue,
2364 ControlFlow::Break(value) => return Ok(value),
2365 }
2366 }
2367 }
2368}
2369
2370#[derive(Default)]
2388pub struct ScanOptions {
2389 pattern: Option<String>,
2390 count: Option<usize>,
2391 scan_type: Option<String>,
2392}
2393
2394impl ScanOptions {
2395 pub fn with_count(mut self, n: usize) -> Self {
2397 self.count = Some(n);
2398 self
2399 }
2400
2401 pub fn with_pattern(mut self, p: impl Into<String>) -> Self {
2403 self.pattern = Some(p.into());
2404 self
2405 }
2406
2407 pub fn with_type(mut self, t: impl Into<String>) -> Self {
2409 self.scan_type = Some(t.into());
2410 self
2411 }
2412}
2413
2414impl ToRedisArgs for ScanOptions {
2415 fn write_redis_args<W>(&self, out: &mut W)
2416 where
2417 W: ?Sized + RedisWrite,
2418 {
2419 if let Some(p) = &self.pattern {
2420 out.write_arg(b"MATCH");
2421 out.write_arg_fmt(p);
2422 }
2423
2424 if let Some(n) = self.count {
2425 out.write_arg(b"COUNT");
2426 out.write_arg_fmt(n);
2427 }
2428
2429 if let Some(t) = &self.scan_type {
2430 out.write_arg(b"TYPE");
2431 out.write_arg_fmt(t);
2432 }
2433 }
2434
2435 fn num_of_args(&self) -> usize {
2436 let mut len = 0;
2437 if self.pattern.is_some() {
2438 len += 2;
2439 }
2440 if self.count.is_some() {
2441 len += 2;
2442 }
2443 if self.scan_type.is_some() {
2444 len += 2;
2445 }
2446 len
2447 }
2448}
2449
2450#[derive(Default)]
2472pub struct LposOptions {
2473 count: Option<usize>,
2474 maxlen: Option<usize>,
2475 rank: Option<isize>,
2476}
2477
2478impl LposOptions {
2479 pub fn count(mut self, n: usize) -> Self {
2481 self.count = Some(n);
2482 self
2483 }
2484
2485 pub fn rank(mut self, n: isize) -> Self {
2487 self.rank = Some(n);
2488 self
2489 }
2490
2491 pub fn maxlen(mut self, n: usize) -> Self {
2493 self.maxlen = Some(n);
2494 self
2495 }
2496}
2497
2498impl ToRedisArgs for LposOptions {
2499 fn write_redis_args<W>(&self, out: &mut W)
2500 where
2501 W: ?Sized + RedisWrite,
2502 {
2503 if let Some(n) = self.count {
2504 out.write_arg(b"COUNT");
2505 out.write_arg_fmt(n);
2506 }
2507
2508 if let Some(n) = self.rank {
2509 out.write_arg(b"RANK");
2510 out.write_arg_fmt(n);
2511 }
2512
2513 if let Some(n) = self.maxlen {
2514 out.write_arg(b"MAXLEN");
2515 out.write_arg_fmt(n);
2516 }
2517 }
2518
2519 fn num_of_args(&self) -> usize {
2520 let mut len = 0;
2521 if self.count.is_some() {
2522 len += 2;
2523 }
2524 if self.rank.is_some() {
2525 len += 2;
2526 }
2527 if self.maxlen.is_some() {
2528 len += 2;
2529 }
2530 len
2531 }
2532}
2533
2534pub enum Direction {
2536 Left,
2538 Right,
2540}
2541
2542impl ToRedisArgs for Direction {
2543 fn write_redis_args<W>(&self, out: &mut W)
2544 where
2545 W: ?Sized + RedisWrite,
2546 {
2547 let s: &[u8] = match self {
2548 Direction::Left => b"LEFT",
2549 Direction::Right => b"RIGHT",
2550 };
2551 out.write_arg(s);
2552 }
2553}
2554
2555#[derive(Clone, Copy, Default)]
2573pub struct SetOptions {
2574 conditional_set: Option<ExistenceCheck>,
2575 get: bool,
2576 expiration: Option<SetExpiry>,
2577}
2578
2579impl SetOptions {
2580 pub fn conditional_set(mut self, existence_check: ExistenceCheck) -> Self {
2582 self.conditional_set = Some(existence_check);
2583 self
2584 }
2585
2586 pub fn get(mut self, get: bool) -> Self {
2588 self.get = get;
2589 self
2590 }
2591
2592 pub fn with_expiration(mut self, expiration: SetExpiry) -> Self {
2594 self.expiration = Some(expiration);
2595 self
2596 }
2597}
2598
2599impl ToRedisArgs for SetOptions {
2600 fn write_redis_args<W>(&self, out: &mut W)
2601 where
2602 W: ?Sized + RedisWrite,
2603 {
2604 if let Some(ref conditional_set) = self.conditional_set {
2605 match conditional_set {
2606 ExistenceCheck::NX => {
2607 out.write_arg(b"NX");
2608 }
2609 ExistenceCheck::XX => {
2610 out.write_arg(b"XX");
2611 }
2612 }
2613 }
2614 if self.get {
2615 out.write_arg(b"GET");
2616 }
2617 if let Some(ref expiration) = self.expiration {
2618 match expiration {
2619 SetExpiry::EX(secs) => {
2620 out.write_arg(b"EX");
2621 out.write_arg(format!("{}", secs).as_bytes());
2622 }
2623 SetExpiry::PX(millis) => {
2624 out.write_arg(b"PX");
2625 out.write_arg(format!("{}", millis).as_bytes());
2626 }
2627 SetExpiry::EXAT(unix_time) => {
2628 out.write_arg(b"EXAT");
2629 out.write_arg(format!("{}", unix_time).as_bytes());
2630 }
2631 SetExpiry::PXAT(unix_time) => {
2632 out.write_arg(b"PXAT");
2633 out.write_arg(format!("{}", unix_time).as_bytes());
2634 }
2635 SetExpiry::KEEPTTL => {
2636 out.write_arg(b"KEEPTTL");
2637 }
2638 }
2639 }
2640 }
2641}
2642
2643#[derive(Clone, Copy, Default)]
2656pub struct FlushAllOptions {
2657 pub blocking: bool,
2659}
2660
2661impl FlushAllOptions {
2662 pub fn blocking(mut self, blocking: bool) -> Self {
2664 self.blocking = blocking;
2665 self
2666 }
2667}
2668
2669impl ToRedisArgs for FlushAllOptions {
2670 fn write_redis_args<W>(&self, out: &mut W)
2671 where
2672 W: ?Sized + RedisWrite,
2673 {
2674 if self.blocking {
2675 out.write_arg(b"SYNC");
2676 } else {
2677 out.write_arg(b"ASYNC");
2678 };
2679 }
2680}
2681
2682pub type FlushDbOptions = FlushAllOptions;
2684
2685pub fn resp3_hello(connection_info: &RedisConnectionInfo) -> Cmd {
2687 let mut hello_cmd = cmd("HELLO");
2688 hello_cmd.arg("3");
2689 if let Some(password) = &connection_info.password {
2690 let username: &str = match connection_info.username.as_ref() {
2691 None => "default",
2692 Some(username) => username,
2693 };
2694 hello_cmd.arg("AUTH").arg(username).arg(password);
2695 }
2696
2697 hello_cmd
2698}