1use crate::cmd::{cmd, Cmd, Iter};
2use crate::connection::{Connection, ConnectionLike, Msg};
3use crate::pipeline::Pipeline;
4use crate::types::{
5 ExistenceCheck, ExpireOption, Expiry, FieldExistenceCheck, FromRedisValue, NumericBehavior,
6 RedisResult, RedisWrite, 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 cmd("GETEX").arg(key).arg(expire_at)
277 }
278
279 fn get_del<K: ToRedisArgs>(key: K) {
281 cmd("GETDEL").arg(key)
282 }
283
284 fn rename<K: ToRedisArgs, N: ToRedisArgs>(key: K, new_key: N) {
286 cmd("RENAME").arg(key).arg(new_key)
287 }
288
289 fn rename_nx<K: ToRedisArgs, N: ToRedisArgs>(key: K, new_key: N) {
291 cmd("RENAMENX").arg(key).arg(new_key)
292 }
293
294 fn unlink<K: ToRedisArgs>(key: K) {
296 cmd("UNLINK").arg(key)
297 }
298
299 fn append<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
303 cmd("APPEND").arg(key).arg(value)
304 }
305
306 fn incr<K: ToRedisArgs, V: ToRedisArgs>(key: K, delta: V) {
309 cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
310 "INCRBYFLOAT"
311 } else {
312 "INCRBY"
313 }).arg(key).arg(delta)
314 }
315
316 fn decr<K: ToRedisArgs, V: ToRedisArgs>(key: K, delta: V) {
318 cmd("DECRBY").arg(key).arg(delta)
319 }
320
321 fn setbit<K: ToRedisArgs>(key: K, offset: usize, value: bool) {
323 cmd("SETBIT").arg(key).arg(offset).arg(i32::from(value))
324 }
325
326 fn getbit<K: ToRedisArgs>(key: K, offset: usize) {
328 cmd("GETBIT").arg(key).arg(offset)
329 }
330
331 fn bitcount<K: ToRedisArgs>(key: K) {
333 cmd("BITCOUNT").arg(key)
334 }
335
336 fn bitcount_range<K: ToRedisArgs>(key: K, start: usize, end: usize) {
338 cmd("BITCOUNT").arg(key).arg(start).arg(end)
339 }
340
341 fn bit_and<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
344 cmd("BITOP").arg("AND").arg(dstkey).arg(srckeys)
345 }
346
347 fn bit_or<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
350 cmd("BITOP").arg("OR").arg(dstkey).arg(srckeys)
351 }
352
353 fn bit_xor<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
356 cmd("BITOP").arg("XOR").arg(dstkey).arg(srckeys)
357 }
358
359 fn bit_not<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckey: S) {
362 cmd("BITOP").arg("NOT").arg(dstkey).arg(srckey)
363 }
364
365 fn strlen<K: ToRedisArgs>(key: K) {
367 cmd("STRLEN").arg(key)
368 }
369
370 fn hget<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
374 cmd(if field.num_of_args() <= 1 { "HGET" } else { "HMGET" }).arg(key).arg(field)
375 }
376
377 fn hget_ex<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F, expire_at: Expiry) {
379 cmd("HGETEX").arg(key).arg(expire_at).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
380 }
381
382 fn hdel<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
384 cmd("HDEL").arg(key).arg(field)
385 }
386
387 fn hget_del<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
389 cmd("HGETDEL").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
390 }
391
392 fn hset<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
394 cmd("HSET").arg(key).arg(field).arg(value)
395 }
396
397 fn hset_ex<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, hash_field_expiration_options: &'a HashFieldExpirationOptions, fields_values: &'a [(F, V)]) {
399 cmd("HSETEX").arg(key).arg(hash_field_expiration_options).arg("FIELDS").arg(fields_values.len()).arg(fields_values)
400 }
401
402 fn hset_nx<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, field: F, value: V) {
404 cmd("HSETNX").arg(key).arg(field).arg(value)
405 }
406
407 fn hset_multiple<K: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(key: K, items: &'a [(F, V)]) {
409 cmd("HMSET").arg(key).arg(items)
410 }
411
412 fn hincr<K: ToRedisArgs, F: ToRedisArgs, D: ToRedisArgs>(key: K, field: F, delta: D) {
414 cmd(if delta.describe_numeric_behavior() == NumericBehavior::NumberIsFloat {
415 "HINCRBYFLOAT"
416 } else {
417 "HINCRBY"
418 }).arg(key).arg(field).arg(delta)
419 }
420
421 fn hexists<K: ToRedisArgs, F: ToRedisArgs>(key: K, field: F) {
423 cmd("HEXISTS").arg(key).arg(field)
424 }
425
426 fn httl<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
428 cmd("HTTL").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
429 }
430
431 fn hpttl<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
433 cmd("HPTTL").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
434 }
435
436 fn hexpire<K: ToRedisArgs, F: ToRedisArgs>(key: K, seconds: i64, opt: ExpireOption, fields: F) {
438 cmd("HEXPIRE").arg(key).arg(seconds).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
439 }
440
441 fn hexpire_at<K: ToRedisArgs, F: ToRedisArgs>(key: K, ts: i64, opt: ExpireOption, fields: F) {
443 cmd("HEXPIREAT").arg(key).arg(ts).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
444 }
445
446 fn hexpire_time<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
448 cmd("HEXPIRETIME").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
449 }
450
451 fn hpersist<K: ToRedisArgs, F :ToRedisArgs>(key: K, fields: F) {
453 cmd("HPERSIST").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
454 }
455
456 fn hpexpire<K: ToRedisArgs, F: ToRedisArgs>(key: K, milliseconds: i64, opt: ExpireOption, fields: F) {
458 cmd("HPEXPIRE").arg(key).arg(milliseconds).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
459 }
460
461 fn hpexpire_at<K: ToRedisArgs, F: ToRedisArgs>(key: K, ts: i64, opt: ExpireOption, fields: F) {
463 cmd("HPEXPIREAT").arg(key).arg(ts).arg(opt).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
464 }
465
466 fn hpexpire_time<K: ToRedisArgs, F: ToRedisArgs>(key: K, fields: F) {
468 cmd("HPEXPIRETIME").arg(key).arg("FIELDS").arg(fields.num_of_args()).arg(fields)
469 }
470
471 fn hkeys<K: ToRedisArgs>(key: K) {
473 cmd("HKEYS").arg(key)
474 }
475
476 fn hvals<K: ToRedisArgs>(key: K) {
478 cmd("HVALS").arg(key)
479 }
480
481 fn hgetall<K: ToRedisArgs>(key: K) {
483 cmd("HGETALL").arg(key)
484 }
485
486 fn hlen<K: ToRedisArgs>(key: K) {
488 cmd("HLEN").arg(key)
489 }
490
491 fn blmove<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, src_dir: Direction, dst_dir: Direction, timeout: f64) {
496 cmd("BLMOVE").arg(srckey).arg(dstkey).arg(src_dir).arg(dst_dir).arg(timeout)
497 }
498
499 fn blmpop<K: ToRedisArgs>(timeout: f64, numkeys: usize, key: K, dir: Direction, count: usize){
502 cmd("BLMPOP").arg(timeout).arg(numkeys).arg(key).arg(dir).arg("COUNT").arg(count)
503 }
504
505 fn blpop<K: ToRedisArgs>(key: K, timeout: f64) {
507 cmd("BLPOP").arg(key).arg(timeout)
508 }
509
510 fn brpop<K: ToRedisArgs>(key: K, timeout: f64) {
512 cmd("BRPOP").arg(key).arg(timeout)
513 }
514
515 fn brpoplpush<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, timeout: f64) {
518 cmd("BRPOPLPUSH").arg(srckey).arg(dstkey).arg(timeout)
519 }
520
521 fn lindex<K: ToRedisArgs>(key: K, index: isize) {
523 cmd("LINDEX").arg(key).arg(index)
524 }
525
526 fn linsert_before<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
528 key: K, pivot: P, value: V) {
529 cmd("LINSERT").arg(key).arg("BEFORE").arg(pivot).arg(value)
530 }
531
532 fn linsert_after<K: ToRedisArgs, P: ToRedisArgs, V: ToRedisArgs>(
534 key: K, pivot: P, value: V) {
535 cmd("LINSERT").arg(key).arg("AFTER").arg(pivot).arg(value)
536 }
537
538 fn llen<K: ToRedisArgs>(key: K) {
540 cmd("LLEN").arg(key)
541 }
542
543 fn lmove<S: ToRedisArgs, D: ToRedisArgs>(srckey: S, dstkey: D, src_dir: Direction, dst_dir: Direction) {
545 cmd("LMOVE").arg(srckey).arg(dstkey).arg(src_dir).arg(dst_dir)
546 }
547
548 fn lmpop<K: ToRedisArgs>( numkeys: usize, key: K, dir: Direction, count: usize) {
551 cmd("LMPOP").arg(numkeys).arg(key).arg(dir).arg("COUNT").arg(count)
552 }
553
554 fn lpop<K: ToRedisArgs>(key: K, count: Option<core::num::NonZeroUsize>) {
558 cmd("LPOP").arg(key).arg(count)
559 }
560
561 fn lpos<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V, options: LposOptions) {
563 cmd("LPOS").arg(key).arg(value).arg(options)
564 }
565
566 fn lpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
568 cmd("LPUSH").arg(key).arg(value)
569 }
570
571 fn lpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
574 cmd("LPUSHX").arg(key).arg(value)
575 }
576
577 fn lrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
579 cmd("LRANGE").arg(key).arg(start).arg(stop)
580 }
581
582 fn lrem<K: ToRedisArgs, V: ToRedisArgs>(key: K, count: isize, value: V) {
585 cmd("LREM").arg(key).arg(count).arg(value)
586 }
587
588 fn ltrim<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
591 cmd("LTRIM").arg(key).arg(start).arg(stop)
592 }
593
594 fn lset<K: ToRedisArgs, V: ToRedisArgs>(key: K, index: isize, value: V) {
596 cmd("LSET").arg(key).arg(index).arg(value)
597 }
598
599 fn ping<>() {
601 &mut cmd("PING")
602 }
603
604 fn ping_message<K: ToRedisArgs>(message: K) {
606 cmd("PING").arg(message)
607 }
608
609 fn rpop<K: ToRedisArgs>(key: K, count: Option<core::num::NonZeroUsize>) {
613 cmd("RPOP").arg(key).arg(count)
614 }
615
616 fn rpoplpush<K: ToRedisArgs, D: ToRedisArgs>(key: K, dstkey: D) {
618 cmd("RPOPLPUSH").arg(key).arg(dstkey)
619 }
620
621 fn rpush<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
623 cmd("RPUSH").arg(key).arg(value)
624 }
625
626 fn rpush_exists<K: ToRedisArgs, V: ToRedisArgs>(key: K, value: V) {
629 cmd("RPUSHX").arg(key).arg(value)
630 }
631
632 fn sadd<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
636 cmd("SADD").arg(key).arg(member)
637 }
638
639 fn scard<K: ToRedisArgs>(key: K) {
641 cmd("SCARD").arg(key)
642 }
643
644 fn sdiff<K: ToRedisArgs>(keys: K) {
646 cmd("SDIFF").arg(keys)
647 }
648
649 fn sdiffstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
651 cmd("SDIFFSTORE").arg(dstkey).arg(keys)
652 }
653
654 fn sinter<K: ToRedisArgs>(keys: K) {
656 cmd("SINTER").arg(keys)
657 }
658
659 fn sinterstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
661 cmd("SINTERSTORE").arg(dstkey).arg(keys)
662 }
663
664 fn sismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
666 cmd("SISMEMBER").arg(key).arg(member)
667 }
668
669 fn smismember<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
671 cmd("SMISMEMBER").arg(key).arg(members)
672 }
673
674 fn smembers<K: ToRedisArgs>(key: K) {
676 cmd("SMEMBERS").arg(key)
677 }
678
679 fn smove<S: ToRedisArgs, D: ToRedisArgs, M: ToRedisArgs>(srckey: S, dstkey: D, member: M) {
681 cmd("SMOVE").arg(srckey).arg(dstkey).arg(member)
682 }
683
684 fn spop<K: ToRedisArgs>(key: K) {
686 cmd("SPOP").arg(key)
687 }
688
689 fn srandmember<K: ToRedisArgs>(key: K) {
691 cmd("SRANDMEMBER").arg(key)
692 }
693
694 fn srandmember_multiple<K: ToRedisArgs>(key: K, count: usize) {
696 cmd("SRANDMEMBER").arg(key).arg(count)
697 }
698
699 fn srem<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
701 cmd("SREM").arg(key).arg(member)
702 }
703
704 fn sunion<K: ToRedisArgs>(keys: K) {
706 cmd("SUNION").arg(keys)
707 }
708
709 fn sunionstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
711 cmd("SUNIONSTORE").arg(dstkey).arg(keys)
712 }
713
714 fn zadd<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, member: M, score: S) {
718 cmd("ZADD").arg(key).arg(score).arg(member)
719 }
720
721 fn zadd_multiple<K: ToRedisArgs, S: ToRedisArgs, M: ToRedisArgs>(key: K, items: &'a [(S, M)]) {
723 cmd("ZADD").arg(key).arg(items)
724 }
725
726 fn zcard<K: ToRedisArgs>(key: K) {
728 cmd("ZCARD").arg(key)
729 }
730
731 fn zcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
733 cmd("ZCOUNT").arg(key).arg(min).arg(max)
734 }
735
736 fn zincr<K: ToRedisArgs, M: ToRedisArgs, D: ToRedisArgs>(key: K, member: M, delta: D) {
739 cmd("ZINCRBY").arg(key).arg(delta).arg(member)
740 }
741
742 fn zinterstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
745 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys)
746 }
747
748 fn zinterstore_min<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
751 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN")
752 }
753
754 fn zinterstore_max<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
757 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX")
758 }
759
760 fn zinterstore_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
764 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
765 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("WEIGHTS").arg(weights)
766 }
767
768 fn zinterstore_min_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
772 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
773 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN").arg("WEIGHTS").arg(weights)
774 }
775
776 fn zinterstore_max_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
780 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
781 cmd("ZINTERSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX").arg("WEIGHTS").arg(weights)
782 }
783
784 fn zlexcount<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
786 cmd("ZLEXCOUNT").arg(key).arg(min).arg(max)
787 }
788
789 fn bzpopmax<K: ToRedisArgs>(key: K, timeout: f64) {
792 cmd("BZPOPMAX").arg(key).arg(timeout)
793 }
794
795 fn zpopmax<K: ToRedisArgs>(key: K, count: isize) {
797 cmd("ZPOPMAX").arg(key).arg(count)
798 }
799
800 fn bzpopmin<K: ToRedisArgs>(key: K, timeout: f64) {
803 cmd("BZPOPMIN").arg(key).arg(timeout)
804 }
805
806 fn zpopmin<K: ToRedisArgs>(key: K, count: isize) {
808 cmd("ZPOPMIN").arg(key).arg(count)
809 }
810
811 fn bzmpop_max<K: ToRedisArgs>(timeout: f64, keys: K, count: isize) {
815 cmd("BZMPOP").arg(timeout).arg(keys.num_of_args()).arg(keys).arg("MAX").arg("COUNT").arg(count)
816 }
817
818 fn zmpop_max<K: ToRedisArgs>(keys: K, count: isize) {
821 cmd("ZMPOP").arg(keys.num_of_args()).arg(keys).arg("MAX").arg("COUNT").arg(count)
822 }
823
824 fn bzmpop_min<K: ToRedisArgs>(timeout: f64, keys: K, count: isize) {
828 cmd("BZMPOP").arg(timeout).arg(keys.num_of_args()).arg(keys).arg("MIN").arg("COUNT").arg(count)
829 }
830
831 fn zmpop_min<K: ToRedisArgs>(keys: K, count: isize) {
834 cmd("ZMPOP").arg(keys.num_of_args()).arg(keys).arg("MIN").arg("COUNT").arg(count)
835 }
836
837 fn zrandmember<K: ToRedisArgs>(key: K, count: Option<isize>) {
839 cmd("ZRANDMEMBER").arg(key).arg(count)
840 }
841
842 fn zrandmember_withscores<K: ToRedisArgs>(key: K, count: isize) {
844 cmd("ZRANDMEMBER").arg(key).arg(count).arg("WITHSCORES")
845 }
846
847 fn zrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
849 cmd("ZRANGE").arg(key).arg(start).arg(stop)
850 }
851
852 fn zrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
854 cmd("ZRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
855 }
856
857 fn zrangebylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
859 cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max)
860 }
861
862 fn zrangebylex_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(
865 key: K, min: M, max: MM, offset: isize, count: isize) {
866 cmd("ZRANGEBYLEX").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
867 }
868
869 fn zrevrangebylex<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
871 cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min)
872 }
873
874 fn zrevrangebylex_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(
877 key: K, max: MM, min: M, offset: isize, count: isize) {
878 cmd("ZREVRANGEBYLEX").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
879 }
880
881 fn zrangebyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
883 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max)
884 }
885
886 fn zrangebyscore_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
888 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
889 }
890
891 fn zrangebyscore_limit<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
893 (key: K, min: M, max: MM, offset: isize, count: isize) {
894 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("LIMIT").arg(offset).arg(count)
895 }
896
897 fn zrangebyscore_limit_withscores<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>
899 (key: K, min: M, max: MM, offset: isize, count: isize) {
900 cmd("ZRANGEBYSCORE").arg(key).arg(min).arg(max).arg("WITHSCORES")
901 .arg("LIMIT").arg(offset).arg(count)
902 }
903
904 fn zrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
906 cmd("ZRANK").arg(key).arg(member)
907 }
908
909 fn zrem<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
911 cmd("ZREM").arg(key).arg(members)
912 }
913
914 fn zrembylex<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
916 cmd("ZREMRANGEBYLEX").arg(key).arg(min).arg(max)
917 }
918
919 fn zremrangebyrank<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
921 cmd("ZREMRANGEBYRANK").arg(key).arg(start).arg(stop)
922 }
923
924 fn zrembyscore<K: ToRedisArgs, M: ToRedisArgs, MM: ToRedisArgs>(key: K, min: M, max: MM) {
926 cmd("ZREMRANGEBYSCORE").arg(key).arg(min).arg(max)
927 }
928
929 fn zrevrange<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
932 cmd("ZREVRANGE").arg(key).arg(start).arg(stop)
933 }
934
935 fn zrevrange_withscores<K: ToRedisArgs>(key: K, start: isize, stop: isize) {
938 cmd("ZREVRANGE").arg(key).arg(start).arg(stop).arg("WITHSCORES")
939 }
940
941 fn zrevrangebyscore<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
943 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min)
944 }
945
946 fn zrevrangebyscore_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>(key: K, max: MM, min: M) {
948 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
949 }
950
951 fn zrevrangebyscore_limit<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
953 (key: K, max: MM, min: M, offset: isize, count: isize) {
954 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("LIMIT").arg(offset).arg(count)
955 }
956
957 fn zrevrangebyscore_limit_withscores<K: ToRedisArgs, MM: ToRedisArgs, M: ToRedisArgs>
959 (key: K, max: MM, min: M, offset: isize, count: isize) {
960 cmd("ZREVRANGEBYSCORE").arg(key).arg(max).arg(min).arg("WITHSCORES")
961 .arg("LIMIT").arg(offset).arg(count)
962 }
963
964 fn zrevrank<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
966 cmd("ZREVRANK").arg(key).arg(member)
967 }
968
969 fn zscore<K: ToRedisArgs, M: ToRedisArgs>(key: K, member: M) {
971 cmd("ZSCORE").arg(key).arg(member)
972 }
973
974 fn zscore_multiple<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: &'a [M]) {
976 cmd("ZMSCORE").arg(key).arg(members)
977 }
978
979 fn zunionstore<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
982 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys)
983 }
984
985 fn zunionstore_min<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
988 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN")
989 }
990
991 fn zunionstore_max<D: ToRedisArgs, K: ToRedisArgs>(dstkey: D, keys: K) {
994 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX")
995 }
996
997 fn zunionstore_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
1001 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
1002 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("WEIGHTS").arg(weights)
1003 }
1004
1005 fn zunionstore_min_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
1009 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
1010 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MIN").arg("WEIGHTS").arg(weights)
1011 }
1012
1013 fn zunionstore_max_weights<D: ToRedisArgs, K: ToRedisArgs, W: ToRedisArgs>(dstkey: D, keys: &'a [(K, W)]) {
1017 let (keys, weights): (Vec<&K>, Vec<&W>) = keys.iter().map(|(key, weight):&(K, W)| -> (&K, &W) {(key, weight)}).unzip();
1018 cmd("ZUNIONSTORE").arg(dstkey).arg(keys.num_of_args()).arg(keys).arg("AGGREGATE").arg("MAX").arg("WEIGHTS").arg(weights)
1019 }
1020
1021 fn pfadd<K: ToRedisArgs, E: ToRedisArgs>(key: K, element: E) {
1025 cmd("PFADD").arg(key).arg(element)
1026 }
1027
1028 fn pfcount<K: ToRedisArgs>(key: K) {
1031 cmd("PFCOUNT").arg(key)
1032 }
1033
1034 fn pfmerge<D: ToRedisArgs, S: ToRedisArgs>(dstkey: D, srckeys: S) {
1036 cmd("PFMERGE").arg(dstkey).arg(srckeys)
1037 }
1038
1039 fn publish<K: ToRedisArgs, E: ToRedisArgs>(channel: K, message: E) {
1041 cmd("PUBLISH").arg(channel).arg(message)
1042 }
1043
1044 fn spublish<K: ToRedisArgs, E: ToRedisArgs>(channel: K, message: E) {
1046 cmd("SPUBLISH").arg(channel).arg(message)
1047 }
1048
1049 fn object_encoding<K: ToRedisArgs>(key: K) {
1053 cmd("OBJECT").arg("ENCODING").arg(key)
1054 }
1055
1056 fn object_idletime<K: ToRedisArgs>(key: K) {
1058 cmd("OBJECT").arg("IDLETIME").arg(key)
1059 }
1060
1061 fn object_freq<K: ToRedisArgs>(key: K) {
1063 cmd("OBJECT").arg("FREQ").arg(key)
1064 }
1065
1066 fn object_refcount<K: ToRedisArgs>(key: K) {
1068 cmd("OBJECT").arg("REFCOUNT").arg(key)
1069 }
1070
1071 fn client_getname<>() {
1073 cmd("CLIENT").arg("GETNAME")
1074 }
1075
1076 fn client_id<>() {
1078 cmd("CLIENT").arg("ID")
1079 }
1080
1081 fn client_setname<K: ToRedisArgs>(connection_name: K) {
1083 cmd("CLIENT").arg("SETNAME").arg(connection_name)
1084 }
1085
1086 #[cfg(feature = "acl")]
1092 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1093 fn acl_load<>() {
1094 cmd("ACL").arg("LOAD")
1095 }
1096
1097 #[cfg(feature = "acl")]
1101 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1102 fn acl_save<>() {
1103 cmd("ACL").arg("SAVE")
1104 }
1105
1106 #[cfg(feature = "acl")]
1108 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1109 fn acl_list<>() {
1110 cmd("ACL").arg("LIST")
1111 }
1112
1113 #[cfg(feature = "acl")]
1116 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1117 fn acl_users<>() {
1118 cmd("ACL").arg("USERS")
1119 }
1120
1121 #[cfg(feature = "acl")]
1123 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1124 fn acl_getuser<K: ToRedisArgs>(username: K) {
1125 cmd("ACL").arg("GETUSER").arg(username)
1126 }
1127
1128 #[cfg(feature = "acl")]
1130 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1131 fn acl_setuser<K: ToRedisArgs>(username: K) {
1132 cmd("ACL").arg("SETUSER").arg(username)
1133 }
1134
1135 #[cfg(feature = "acl")]
1138 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1139 fn acl_setuser_rules<K: ToRedisArgs>(username: K, rules: &'a [acl::Rule]) {
1140 cmd("ACL").arg("SETUSER").arg(username).arg(rules)
1141 }
1142
1143 #[cfg(feature = "acl")]
1146 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1147 fn acl_deluser<K: ToRedisArgs>(usernames: &'a [K]) {
1148 cmd("ACL").arg("DELUSER").arg(usernames)
1149 }
1150
1151 #[cfg(feature = "acl")]
1153 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1154 fn acl_dryrun<K: ToRedisArgs, C: ToRedisArgs, A: ToRedisArgs>(username: K, command: C, args: A) {
1155 cmd("ACL").arg("DRYRUN").arg(username).arg(command).arg(args)
1156 }
1157
1158 #[cfg(feature = "acl")]
1160 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1161 fn acl_cat<>() {
1162 cmd("ACL").arg("CAT")
1163 }
1164
1165 #[cfg(feature = "acl")]
1167 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1168 fn acl_cat_categoryname<K: ToRedisArgs>(categoryname: K) {
1169 cmd("ACL").arg("CAT").arg(categoryname)
1170 }
1171
1172 #[cfg(feature = "acl")]
1174 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1175 fn acl_genpass<>() {
1176 cmd("ACL").arg("GENPASS")
1177 }
1178
1179 #[cfg(feature = "acl")]
1181 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1182 fn acl_genpass_bits<>(bits: isize) {
1183 cmd("ACL").arg("GENPASS").arg(bits)
1184 }
1185
1186 #[cfg(feature = "acl")]
1188 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1189 fn acl_whoami<>() {
1190 cmd("ACL").arg("WHOAMI")
1191 }
1192
1193 #[cfg(feature = "acl")]
1195 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1196 fn acl_log<>(count: isize) {
1197 cmd("ACL").arg("LOG").arg(count)
1198
1199 }
1200
1201 #[cfg(feature = "acl")]
1203 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1204 fn acl_log_reset<>() {
1205 cmd("ACL").arg("LOG").arg("RESET")
1206 }
1207
1208 #[cfg(feature = "acl")]
1210 #[cfg_attr(docsrs, doc(cfg(feature = "acl")))]
1211 fn acl_help<>() {
1212 cmd("ACL").arg("HELP")
1213 }
1214
1215 #[cfg(feature = "geospatial")]
1253 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1254 fn geo_add<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1255 cmd("GEOADD").arg(key).arg(members)
1256 }
1257
1258 #[cfg(feature = "geospatial")]
1290 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1291 fn geo_dist<K: ToRedisArgs, M1: ToRedisArgs, M2: ToRedisArgs>(
1292 key: K,
1293 member1: M1,
1294 member2: M2,
1295 unit: geo::Unit
1296 ) {
1297 cmd("GEODIST")
1298 .arg(key)
1299 .arg(member1)
1300 .arg(member2)
1301 .arg(unit)
1302 }
1303
1304 #[cfg(feature = "geospatial")]
1324 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1325 fn geo_hash<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1326 cmd("GEOHASH").arg(key).arg(members)
1327 }
1328
1329 #[cfg(feature = "geospatial")]
1353 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1354 fn geo_pos<K: ToRedisArgs, M: ToRedisArgs>(key: K, members: M) {
1355 cmd("GEOPOS").arg(key).arg(members)
1356 }
1357
1358 #[cfg(feature = "geospatial")]
1378 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1379 fn geo_radius<K: ToRedisArgs>(
1380 key: K,
1381 longitude: f64,
1382 latitude: f64,
1383 radius: f64,
1384 unit: geo::Unit,
1385 options: geo::RadiusOptions
1386 ) {
1387 cmd("GEORADIUS")
1388 .arg(key)
1389 .arg(longitude)
1390 .arg(latitude)
1391 .arg(radius)
1392 .arg(unit)
1393 .arg(options)
1394 }
1395
1396 #[cfg(feature = "geospatial")]
1399 #[cfg_attr(docsrs, doc(cfg(feature = "geospatial")))]
1400 fn geo_radius_by_member<K: ToRedisArgs, M: ToRedisArgs>(
1401 key: K,
1402 member: M,
1403 radius: f64,
1404 unit: geo::Unit,
1405 options: geo::RadiusOptions
1406 ) {
1407 cmd("GEORADIUSBYMEMBER")
1408 .arg(key)
1409 .arg(member)
1410 .arg(radius)
1411 .arg(unit)
1412 .arg(options)
1413 }
1414
1415 #[cfg(feature = "streams")]
1425 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1426 fn xack<K: ToRedisArgs, G: ToRedisArgs, I: ToRedisArgs>(
1427 key: K,
1428 group: G,
1429 ids: &'a [I]) {
1430 cmd("XACK")
1431 .arg(key)
1432 .arg(group)
1433 .arg(ids)
1434 }
1435
1436
1437 #[cfg(feature = "streams")]
1443 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1444 fn xadd<K: ToRedisArgs, ID: ToRedisArgs, F: ToRedisArgs, V: ToRedisArgs>(
1445 key: K,
1446 id: ID,
1447 items: &'a [(F, V)]
1448 ) {
1449 cmd("XADD").arg(key).arg(id).arg(items)
1450 }
1451
1452
1453 #[cfg(feature = "streams")]
1460 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1461 fn xadd_map<K: ToRedisArgs, ID: ToRedisArgs, BTM: ToRedisArgs>(
1462 key: K,
1463 id: ID,
1464 map: BTM
1465 ) {
1466 cmd("XADD").arg(key).arg(id).arg(map)
1467 }
1468
1469
1470 #[cfg(feature = "streams")]
1488 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1489 fn xadd_options<
1490 K: ToRedisArgs, ID: ToRedisArgs, I: ToRedisArgs
1491 >(
1492 key: K,
1493 id: ID,
1494 items: I,
1495 options: &'a streams::StreamAddOptions
1496 ) {
1497 cmd("XADD")
1498 .arg(key)
1499 .arg(options)
1500 .arg(id)
1501 .arg(items)
1502 }
1503
1504
1505 #[cfg(feature = "streams")]
1511 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1512 fn xadd_maxlen<
1513 K: ToRedisArgs,
1514 ID: ToRedisArgs,
1515 F: ToRedisArgs,
1516 V: ToRedisArgs
1517 >(
1518 key: K,
1519 maxlen: streams::StreamMaxlen,
1520 id: ID,
1521 items: &'a [(F, V)]
1522 ) {
1523 cmd("XADD")
1524 .arg(key)
1525 .arg(maxlen)
1526 .arg(id)
1527 .arg(items)
1528 }
1529
1530
1531 #[cfg(feature = "streams")]
1537 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1538 fn xadd_maxlen_map<K: ToRedisArgs, ID: ToRedisArgs, BTM: ToRedisArgs>(
1539 key: K,
1540 maxlen: streams::StreamMaxlen,
1541 id: ID,
1542 map: BTM
1543 ) {
1544 cmd("XADD")
1545 .arg(key)
1546 .arg(maxlen)
1547 .arg(id)
1548 .arg(map)
1549 }
1550
1551 #[cfg(feature = "streams")]
1567 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1568 fn xautoclaim_options<
1569 K: ToRedisArgs,
1570 G: ToRedisArgs,
1571 C: ToRedisArgs,
1572 MIT: ToRedisArgs,
1573 S: ToRedisArgs
1574 >(
1575 key: K,
1576 group: G,
1577 consumer: C,
1578 min_idle_time: MIT,
1579 start: S,
1580 options: streams::StreamAutoClaimOptions
1581 ) {
1582 cmd("XAUTOCLAIM")
1583 .arg(key)
1584 .arg(group)
1585 .arg(consumer)
1586 .arg(min_idle_time)
1587 .arg(start)
1588 .arg(options)
1589 }
1590
1591 #[cfg(feature = "streams")]
1601 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1602 fn xclaim<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs, MIT: ToRedisArgs, ID: ToRedisArgs>(
1603 key: K,
1604 group: G,
1605 consumer: C,
1606 min_idle_time: MIT,
1607 ids: &'a [ID]
1608 ) {
1609 cmd("XCLAIM")
1610 .arg(key)
1611 .arg(group)
1612 .arg(consumer)
1613 .arg(min_idle_time)
1614 .arg(ids)
1615 }
1616
1617 #[cfg(feature = "streams")]
1651 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1652 fn xclaim_options<
1653 K: ToRedisArgs,
1654 G: ToRedisArgs,
1655 C: ToRedisArgs,
1656 MIT: ToRedisArgs,
1657 ID: ToRedisArgs
1658 >(
1659 key: K,
1660 group: G,
1661 consumer: C,
1662 min_idle_time: MIT,
1663 ids: &'a [ID],
1664 options: streams::StreamClaimOptions
1665 ) {
1666 cmd("XCLAIM")
1667 .arg(key)
1668 .arg(group)
1669 .arg(consumer)
1670 .arg(min_idle_time)
1671 .arg(ids)
1672 .arg(options)
1673 }
1674
1675
1676 #[cfg(feature = "streams")]
1682 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1683 fn xdel<K: ToRedisArgs, ID: ToRedisArgs>(
1684 key: K,
1685 ids: &'a [ID]
1686 ) {
1687 cmd("XDEL").arg(key).arg(ids)
1688 }
1689
1690
1691 #[cfg(feature = "streams")]
1700 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1701 fn xgroup_create<K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs>(
1702 key: K,
1703 group: G,
1704 id: ID
1705 ) {
1706 cmd("XGROUP")
1707 .arg("CREATE")
1708 .arg(key)
1709 .arg(group)
1710 .arg(id)
1711 }
1712
1713 #[cfg(feature = "streams")]
1723 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1724 fn xgroup_createconsumer<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs>(
1725 key: K,
1726 group: G,
1727 consumer: C
1728 ) {
1729 cmd("XGROUP")
1730 .arg("CREATECONSUMER")
1731 .arg(key)
1732 .arg(group)
1733 .arg(consumer)
1734 }
1735
1736 #[cfg(feature = "streams")]
1743 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1744 fn xgroup_create_mkstream<
1745 K: ToRedisArgs,
1746 G: ToRedisArgs,
1747 ID: ToRedisArgs
1748 >(
1749 key: K,
1750 group: G,
1751 id: ID
1752 ) {
1753 cmd("XGROUP")
1754 .arg("CREATE")
1755 .arg(key)
1756 .arg(group)
1757 .arg(id)
1758 .arg("MKSTREAM")
1759 }
1760
1761
1762 #[cfg(feature = "streams")]
1769 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1770 fn xgroup_setid<K: ToRedisArgs, G: ToRedisArgs, ID: ToRedisArgs>(
1771 key: K,
1772 group: G,
1773 id: ID
1774 ) {
1775 cmd("XGROUP")
1776 .arg("SETID")
1777 .arg(key)
1778 .arg(group)
1779 .arg(id)
1780 }
1781
1782
1783 #[cfg(feature = "streams")]
1789 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1790 fn xgroup_destroy<K: ToRedisArgs, G: ToRedisArgs>(
1791 key: K,
1792 group: G
1793 ) {
1794 cmd("XGROUP").arg("DESTROY").arg(key).arg(group)
1795 }
1796
1797 #[cfg(feature = "streams")]
1804 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1805 fn xgroup_delconsumer<K: ToRedisArgs, G: ToRedisArgs, C: ToRedisArgs>(
1806 key: K,
1807 group: G,
1808 consumer: C
1809 ) {
1810 cmd("XGROUP")
1811 .arg("DELCONSUMER")
1812 .arg(key)
1813 .arg(group)
1814 .arg(consumer)
1815 }
1816
1817
1818 #[cfg(feature = "streams")]
1829 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1830 fn xinfo_consumers<K: ToRedisArgs, G: ToRedisArgs>(
1831 key: K,
1832 group: G
1833 ) {
1834 cmd("XINFO")
1835 .arg("CONSUMERS")
1836 .arg(key)
1837 .arg(group)
1838 }
1839
1840
1841 #[cfg(feature = "streams")]
1851 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1852 fn xinfo_groups<K: ToRedisArgs>(key: K) {
1853 cmd("XINFO").arg("GROUPS").arg(key)
1854 }
1855
1856
1857 #[cfg(feature = "streams")]
1868 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1869 fn xinfo_stream<K: ToRedisArgs>(key: K) {
1870 cmd("XINFO").arg("STREAM").arg(key)
1871 }
1872
1873 #[cfg(feature = "streams")]
1879 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1880 fn xlen<K: ToRedisArgs>(key: K) {
1881 cmd("XLEN").arg(key)
1882 }
1883
1884
1885 #[cfg(feature = "streams")]
1900 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1901 fn xpending<K: ToRedisArgs, G: ToRedisArgs>(
1902 key: K,
1903 group: G
1904 ) {
1905 cmd("XPENDING").arg(key).arg(group)
1906 }
1907
1908
1909 #[cfg(feature = "streams")]
1921 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1922 fn xpending_count<
1923 K: ToRedisArgs,
1924 G: ToRedisArgs,
1925 S: ToRedisArgs,
1926 E: ToRedisArgs,
1927 C: ToRedisArgs
1928 >(
1929 key: K,
1930 group: G,
1931 start: S,
1932 end: E,
1933 count: C
1934 ) {
1935 cmd("XPENDING")
1936 .arg(key)
1937 .arg(group)
1938 .arg(start)
1939 .arg(end)
1940 .arg(count)
1941 }
1942
1943
1944 #[cfg(feature = "streams")]
1955 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1956 fn xpending_consumer_count<
1957 K: ToRedisArgs,
1958 G: ToRedisArgs,
1959 S: ToRedisArgs,
1960 E: ToRedisArgs,
1961 C: ToRedisArgs,
1962 CN: ToRedisArgs
1963 >(
1964 key: K,
1965 group: G,
1966 start: S,
1967 end: E,
1968 count: C,
1969 consumer: CN
1970 ) {
1971 cmd("XPENDING")
1972 .arg(key)
1973 .arg(group)
1974 .arg(start)
1975 .arg(end)
1976 .arg(count)
1977 .arg(consumer)
1978 }
1979
1980 #[cfg(feature = "streams")]
1992 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
1993 fn xrange<K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs>(
1994 key: K,
1995 start: S,
1996 end: E
1997 ) {
1998 cmd("XRANGE").arg(key).arg(start).arg(end)
1999 }
2000
2001
2002 #[cfg(feature = "streams")]
2009 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2010 fn xrange_all<K: ToRedisArgs>(key: K) {
2011 cmd("XRANGE").arg(key).arg("-").arg("+")
2012 }
2013
2014
2015 #[cfg(feature = "streams")]
2021 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2022 fn xrange_count<K: ToRedisArgs, S: ToRedisArgs, E: ToRedisArgs, C: ToRedisArgs>(
2023 key: K,
2024 start: S,
2025 end: E,
2026 count: C
2027 ) {
2028 cmd("XRANGE")
2029 .arg(key)
2030 .arg(start)
2031 .arg(end)
2032 .arg("COUNT")
2033 .arg(count)
2034 }
2035
2036
2037 #[cfg(feature = "streams")]
2046 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2047 fn xread<K: ToRedisArgs, ID: ToRedisArgs>(
2048 keys: &'a [K],
2049 ids: &'a [ID]
2050 ) {
2051 cmd("XREAD").arg("STREAMS").arg(keys).arg(ids)
2052 }
2053
2054 #[cfg(feature = "streams")]
2091 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2092 fn xread_options<K: ToRedisArgs, ID: ToRedisArgs>(
2093 keys: &'a [K],
2094 ids: &'a [ID],
2095 options: &'a streams::StreamReadOptions
2096 ) {
2097 cmd(if options.read_only() {
2098 "XREAD"
2099 } else {
2100 "XREADGROUP"
2101 })
2102 .arg(options)
2103 .arg("STREAMS")
2104 .arg(keys)
2105 .arg(ids)
2106 }
2107
2108 #[cfg(feature = "streams")]
2115 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2116 fn xrevrange<K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs>(
2117 key: K,
2118 end: E,
2119 start: S
2120 ) {
2121 cmd("XREVRANGE").arg(key).arg(end).arg(start)
2122 }
2123
2124 fn xrevrange_all<K: ToRedisArgs>(key: K) {
2131 cmd("XREVRANGE").arg(key).arg("+").arg("-")
2132 }
2133
2134 #[cfg(feature = "streams")]
2141 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2142 fn xrevrange_count<K: ToRedisArgs, E: ToRedisArgs, S: ToRedisArgs, C: ToRedisArgs>(
2143 key: K,
2144 end: E,
2145 start: S,
2146 count: C
2147 ) {
2148 cmd("XREVRANGE")
2149 .arg(key)
2150 .arg(end)
2151 .arg(start)
2152 .arg("COUNT")
2153 .arg(count)
2154 }
2155
2156 #[cfg(feature = "streams")]
2162 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2163 fn xtrim<K: ToRedisArgs>(
2164 key: K,
2165 maxlen: streams::StreamMaxlen
2166 ) {
2167 cmd("XTRIM").arg(key).arg(maxlen)
2168 }
2169
2170 #[cfg(feature = "streams")]
2176 #[cfg_attr(docsrs, doc(cfg(feature = "streams")))]
2177 fn xtrim_options<K: ToRedisArgs>(
2178 key: K,
2179 options: &'a streams::StreamTrimOptions
2180 ) {
2181 cmd("XTRIM").arg(key).arg(options)
2182 }
2183
2184 #[cfg_attr(feature = "script", doc = r##"
2192
2193# Examples:
2194
2195```rust,no_run
2196# fn do_something() -> redis::RedisResult<()> {
2197# let client = redis::Client::open("redis://127.0.0.1/").unwrap();
2198# let mut con = client.get_connection().unwrap();
2199let script = redis::Script::new(r"
2200 return tonumber(ARGV[1]) + tonumber(ARGV[2]);
2201");
2202script.prepare_invoke().load(&mut con)?;
2203let (a, b): (isize, isize) = redis::pipe()
2204 .invoke_script(script.arg(1).arg(2))
2205 .invoke_script(script.arg(2).arg(3))
2206 .query(&mut con)?;
2207
2208assert_eq!(a, 3);
2209assert_eq!(b, 5);
2210# Ok(()) }
2211```
2212"##)]
2213 #[cfg(feature = "script")]
2214 #[cfg_attr(docsrs, doc(cfg(feature = "script")))]
2215 fn invoke_script<>(invocation: &'a crate::ScriptInvocation<'a>) {
2216 &mut invocation.eval_cmd()
2217 }
2218
2219 fn flushall<>() {
2232 &mut cmd("FLUSHALL")
2233 }
2234
2235 fn flushall_options<>(options: &'a FlushAllOptions) {
2241 cmd("FLUSHALL").arg(options)
2242 }
2243
2244 fn flushdb<>() {
2255 &mut cmd("FLUSHDB")
2256 }
2257
2258 fn flushdb_options<>(options: &'a FlushDbOptions) {
2264 cmd("FLUSHDB").arg(options)
2265 }
2266}
2267
2268pub enum ControlFlow<U> {
2272 Continue,
2274 Break(U),
2276}
2277
2278pub trait PubSubCommands: Sized {
2313 fn subscribe<C, F, U>(&mut self, _: C, _: F) -> RedisResult<U>
2320 where
2321 F: FnMut(Msg) -> ControlFlow<U>,
2322 C: ToRedisArgs;
2323
2324 fn psubscribe<P, F, U>(&mut self, _: P, _: F) -> RedisResult<U>
2331 where
2332 F: FnMut(Msg) -> ControlFlow<U>,
2333 P: ToRedisArgs;
2334}
2335
2336impl<T> Commands for T where T: ConnectionLike {}
2337
2338#[cfg(feature = "aio")]
2339impl<T> AsyncCommands for T where T: crate::aio::ConnectionLike + Send + Sync + Sized {}
2340
2341impl PubSubCommands for Connection {
2342 fn subscribe<C, F, U>(&mut self, channels: C, mut func: F) -> RedisResult<U>
2343 where
2344 F: FnMut(Msg) -> ControlFlow<U>,
2345 C: ToRedisArgs,
2346 {
2347 let mut pubsub = self.as_pubsub();
2348 pubsub.subscribe(channels)?;
2349
2350 loop {
2351 let msg = pubsub.get_message()?;
2352 match func(msg) {
2353 ControlFlow::Continue => continue,
2354 ControlFlow::Break(value) => return Ok(value),
2355 }
2356 }
2357 }
2358
2359 fn psubscribe<P, F, U>(&mut self, patterns: P, mut func: F) -> RedisResult<U>
2360 where
2361 F: FnMut(Msg) -> ControlFlow<U>,
2362 P: ToRedisArgs,
2363 {
2364 let mut pubsub = self.as_pubsub();
2365 pubsub.psubscribe(patterns)?;
2366
2367 loop {
2368 let msg = pubsub.get_message()?;
2369 match func(msg) {
2370 ControlFlow::Continue => continue,
2371 ControlFlow::Break(value) => return Ok(value),
2372 }
2373 }
2374 }
2375}
2376
2377#[derive(Default)]
2395pub struct ScanOptions {
2396 pattern: Option<String>,
2397 count: Option<usize>,
2398 scan_type: Option<String>,
2399}
2400
2401impl ScanOptions {
2402 pub fn with_count(mut self, n: usize) -> Self {
2404 self.count = Some(n);
2405 self
2406 }
2407
2408 pub fn with_pattern(mut self, p: impl Into<String>) -> Self {
2410 self.pattern = Some(p.into());
2411 self
2412 }
2413
2414 pub fn with_type(mut self, t: impl Into<String>) -> Self {
2416 self.scan_type = Some(t.into());
2417 self
2418 }
2419}
2420
2421impl ToRedisArgs for ScanOptions {
2422 fn write_redis_args<W>(&self, out: &mut W)
2423 where
2424 W: ?Sized + RedisWrite,
2425 {
2426 if let Some(p) = &self.pattern {
2427 out.write_arg(b"MATCH");
2428 out.write_arg_fmt(p);
2429 }
2430
2431 if let Some(n) = self.count {
2432 out.write_arg(b"COUNT");
2433 out.write_arg_fmt(n);
2434 }
2435
2436 if let Some(t) = &self.scan_type {
2437 out.write_arg(b"TYPE");
2438 out.write_arg_fmt(t);
2439 }
2440 }
2441
2442 fn num_of_args(&self) -> usize {
2443 let mut len = 0;
2444 if self.pattern.is_some() {
2445 len += 2;
2446 }
2447 if self.count.is_some() {
2448 len += 2;
2449 }
2450 if self.scan_type.is_some() {
2451 len += 2;
2452 }
2453 len
2454 }
2455}
2456
2457#[derive(Default)]
2479pub struct LposOptions {
2480 count: Option<usize>,
2481 maxlen: Option<usize>,
2482 rank: Option<isize>,
2483}
2484
2485impl LposOptions {
2486 pub fn count(mut self, n: usize) -> Self {
2488 self.count = Some(n);
2489 self
2490 }
2491
2492 pub fn rank(mut self, n: isize) -> Self {
2494 self.rank = Some(n);
2495 self
2496 }
2497
2498 pub fn maxlen(mut self, n: usize) -> Self {
2500 self.maxlen = Some(n);
2501 self
2502 }
2503}
2504
2505impl ToRedisArgs for LposOptions {
2506 fn write_redis_args<W>(&self, out: &mut W)
2507 where
2508 W: ?Sized + RedisWrite,
2509 {
2510 if let Some(n) = self.count {
2511 out.write_arg(b"COUNT");
2512 out.write_arg_fmt(n);
2513 }
2514
2515 if let Some(n) = self.rank {
2516 out.write_arg(b"RANK");
2517 out.write_arg_fmt(n);
2518 }
2519
2520 if let Some(n) = self.maxlen {
2521 out.write_arg(b"MAXLEN");
2522 out.write_arg_fmt(n);
2523 }
2524 }
2525
2526 fn num_of_args(&self) -> usize {
2527 let mut len = 0;
2528 if self.count.is_some() {
2529 len += 2;
2530 }
2531 if self.rank.is_some() {
2532 len += 2;
2533 }
2534 if self.maxlen.is_some() {
2535 len += 2;
2536 }
2537 len
2538 }
2539}
2540
2541pub enum Direction {
2543 Left,
2545 Right,
2547}
2548
2549impl ToRedisArgs for Direction {
2550 fn write_redis_args<W>(&self, out: &mut W)
2551 where
2552 W: ?Sized + RedisWrite,
2553 {
2554 let s: &[u8] = match self {
2555 Direction::Left => b"LEFT",
2556 Direction::Right => b"RIGHT",
2557 };
2558 out.write_arg(s);
2559 }
2560}
2561
2562#[derive(Clone, Copy, Default)]
2580pub struct SetOptions {
2581 conditional_set: Option<ExistenceCheck>,
2582 get: bool,
2583 expiration: Option<SetExpiry>,
2584}
2585
2586impl SetOptions {
2587 pub fn conditional_set(mut self, existence_check: ExistenceCheck) -> Self {
2589 self.conditional_set = Some(existence_check);
2590 self
2591 }
2592
2593 pub fn get(mut self, get: bool) -> Self {
2595 self.get = get;
2596 self
2597 }
2598
2599 pub fn with_expiration(mut self, expiration: SetExpiry) -> Self {
2601 self.expiration = Some(expiration);
2602 self
2603 }
2604}
2605
2606impl ToRedisArgs for SetOptions {
2607 fn write_redis_args<W>(&self, out: &mut W)
2608 where
2609 W: ?Sized + RedisWrite,
2610 {
2611 if let Some(ref conditional_set) = self.conditional_set {
2612 match conditional_set {
2613 ExistenceCheck::NX => {
2614 out.write_arg(b"NX");
2615 }
2616 ExistenceCheck::XX => {
2617 out.write_arg(b"XX");
2618 }
2619 }
2620 }
2621 if self.get {
2622 out.write_arg(b"GET");
2623 }
2624 if let Some(ref expiration) = self.expiration {
2625 match expiration {
2626 SetExpiry::EX(secs) => {
2627 out.write_arg(b"EX");
2628 out.write_arg(format!("{}", secs).as_bytes());
2629 }
2630 SetExpiry::PX(millis) => {
2631 out.write_arg(b"PX");
2632 out.write_arg(format!("{}", millis).as_bytes());
2633 }
2634 SetExpiry::EXAT(unix_time) => {
2635 out.write_arg(b"EXAT");
2636 out.write_arg(format!("{}", unix_time).as_bytes());
2637 }
2638 SetExpiry::PXAT(unix_time) => {
2639 out.write_arg(b"PXAT");
2640 out.write_arg(format!("{}", unix_time).as_bytes());
2641 }
2642 SetExpiry::KEEPTTL => {
2643 out.write_arg(b"KEEPTTL");
2644 }
2645 }
2646 }
2647 }
2648}
2649
2650#[derive(Clone, Copy, Default)]
2663pub struct FlushAllOptions {
2664 pub blocking: bool,
2666}
2667
2668impl FlushAllOptions {
2669 pub fn blocking(mut self, blocking: bool) -> Self {
2671 self.blocking = blocking;
2672 self
2673 }
2674}
2675
2676impl ToRedisArgs for FlushAllOptions {
2677 fn write_redis_args<W>(&self, out: &mut W)
2678 where
2679 W: ?Sized + RedisWrite,
2680 {
2681 if self.blocking {
2682 out.write_arg(b"SYNC");
2683 } else {
2684 out.write_arg(b"ASYNC");
2685 };
2686 }
2687}
2688
2689pub type FlushDbOptions = FlushAllOptions;
2691
2692#[derive(Clone, Copy, Default)]
2694pub struct HashFieldExpirationOptions {
2695 existence_check: Option<FieldExistenceCheck>,
2696 expiration: Option<SetExpiry>,
2697}
2698
2699impl HashFieldExpirationOptions {
2700 pub fn set_existence_check(mut self, field_existence_check: FieldExistenceCheck) -> Self {
2702 self.existence_check = Some(field_existence_check);
2703 self
2704 }
2705
2706 pub fn set_expiration(mut self, expiration: SetExpiry) -> Self {
2708 self.expiration = Some(expiration);
2709 self
2710 }
2711}
2712
2713impl ToRedisArgs for HashFieldExpirationOptions {
2714 fn write_redis_args<W>(&self, out: &mut W)
2715 where
2716 W: ?Sized + RedisWrite,
2717 {
2718 if let Some(ref existence_check) = self.existence_check {
2719 match existence_check {
2720 FieldExistenceCheck::FNX => out.write_arg(b"FNX"),
2721 FieldExistenceCheck::FXX => out.write_arg(b"FXX"),
2722 }
2723 }
2724
2725 if let Some(ref expiration) = self.expiration {
2726 match expiration {
2727 SetExpiry::EX(secs) => {
2728 out.write_arg(b"EX");
2729 out.write_arg(format!("{}", secs).as_bytes());
2730 }
2731 SetExpiry::PX(millis) => {
2732 out.write_arg(b"PX");
2733 out.write_arg(format!("{}", millis).as_bytes());
2734 }
2735 SetExpiry::EXAT(unix_time) => {
2736 out.write_arg(b"EXAT");
2737 out.write_arg(format!("{}", unix_time).as_bytes());
2738 }
2739 SetExpiry::PXAT(unix_time) => {
2740 out.write_arg(b"PXAT");
2741 out.write_arg(format!("{}", unix_time).as_bytes());
2742 }
2743 SetExpiry::KEEPTTL => {
2744 out.write_arg(b"KEEPTTL");
2745 }
2746 }
2747 }
2748 }
2749}
2750
2751impl ToRedisArgs for Expiry {
2752 fn write_redis_args<W>(&self, out: &mut W)
2753 where
2754 W: ?Sized + RedisWrite,
2755 {
2756 match self {
2757 Expiry::EX(sec) => {
2758 out.write_arg(b"EX");
2759 out.write_arg(sec.to_string().as_bytes());
2760 }
2761 Expiry::PX(ms) => {
2762 out.write_arg(b"PX");
2763 out.write_arg(ms.to_string().as_bytes());
2764 }
2765 Expiry::EXAT(timestamp_sec) => {
2766 out.write_arg(b"EXAT");
2767 out.write_arg(timestamp_sec.to_string().as_bytes());
2768 }
2769 Expiry::PXAT(timestamp_ms) => {
2770 out.write_arg(b"PXAT");
2771 out.write_arg(timestamp_ms.to_string().as_bytes());
2772 }
2773 Expiry::PERSIST => {
2774 out.write_arg(b"PERSIST");
2775 }
2776 }
2777 }
2778}
2779
2780pub fn resp3_hello(connection_info: &RedisConnectionInfo) -> Cmd {
2782 let mut hello_cmd = cmd("HELLO");
2783 hello_cmd.arg("3");
2784 if let Some(password) = &connection_info.password {
2785 let username: &str = match connection_info.username.as_ref() {
2786 None => "default",
2787 Some(username) => username,
2788 };
2789 hello_cmd.arg("AUTH").arg(username).arg(password);
2790 }
2791
2792 hello_cmd
2793}