redis_driver/commands/generic_commands.rs
1use crate::{
2 prepare_command,
3 resp::{
4 cmd, CommandArg, CommandArgs, FromSingleValueArray, FromValue, IntoArgs,
5 SingleArgOrCollection, Value,
6 },
7 Error, PreparedCommand, Result,
8};
9
10/// A group of generic Redis commands
11///
12/// # See Also
13/// [Redis Generic Commands](https://redis.io/commands/?group=generic)
14pub trait GenericCommands {
15 /// This command copies the value stored at the source key to the destination key.
16 ///
17 /// # Return
18 /// Success of the operation
19 ///
20 /// # See Also
21 /// [<https://redis.io/commands/copy/>](https://redis.io/commands/copy/)
22 #[must_use]
23 fn copy<S, D>(
24 &mut self,
25 source: S,
26 destination: D,
27 destination_db: Option<usize>,
28 replace: bool,
29 ) -> PreparedCommand<Self, bool>
30 where
31 Self: Sized,
32 S: Into<CommandArg>,
33 D: Into<CommandArg>,
34 {
35 prepare_command(
36 self,
37 cmd("COPY")
38 .arg(source)
39 .arg(destination)
40 .arg(destination_db.map(|db| ("DB", db)))
41 .arg_if(replace, "REPLACE"),
42 )
43 }
44
45 /// Removes the specified keys. A key is ignored if it does not exist.
46 ///
47 /// # Return
48 /// The number of keys that were removed.
49 ///
50 /// # See Also
51 /// [<https://redis.io/commands/del/>](https://redis.io/commands/del/)
52 #[must_use]
53 fn del<K, C>(&mut self, keys: C) -> PreparedCommand<Self, usize>
54 where
55 Self: Sized,
56 K: Into<CommandArg>,
57 C: SingleArgOrCollection<K>,
58 {
59 prepare_command(self, cmd("DEL").arg(keys))
60 }
61
62 /// Serialize the value stored at key in a Redis-specific format and return it to the user.
63 ///
64 /// # Return
65 /// The serialized value.
66 ///
67 /// # See Also
68 /// [<https://redis.io/commands/dump/>](https://redis.io/commands/dump/)
69 #[must_use]
70 fn dump<K>(&mut self, key: K) -> PreparedCommand<Self, DumpResult>
71 where
72 Self: Sized,
73 K: Into<CommandArg>,
74 {
75 prepare_command(self, cmd("DUMP").arg(key))
76 }
77
78 /// Returns if keys exist.
79 ///
80 /// # Return
81 /// The number of keys that exist from those specified as arguments.
82 ///
83 /// # See Also
84 /// [<https://redis.io/commands/exists/>](https://redis.io/commands/exists/)
85 #[must_use]
86 fn exists<K, C>(&mut self, keys: C) -> PreparedCommand<Self, usize>
87 where
88 Self: Sized,
89 K: Into<CommandArg>,
90 C: SingleArgOrCollection<K>,
91 {
92 prepare_command(self, cmd("EXISTS").arg(keys))
93 }
94
95 /// Set a timeout on key in seconds
96 ///
97 /// # Return
98 /// * `true` - if the timeout was set.
99 /// * `false` - if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments.
100 ///
101 /// # See Also
102 /// [<https://redis.io/commands/expire/>](https://redis.io/commands/expire/)
103 #[must_use]
104 fn expire<K>(
105 &mut self,
106 key: K,
107 seconds: u64,
108 option: ExpireOption,
109 ) -> PreparedCommand<Self, bool>
110 where
111 Self: Sized,
112 K: Into<CommandArg>,
113 {
114 prepare_command(self, cmd("EXPIRE").arg(key).arg(seconds).arg(option))
115 }
116
117 /// EXPIREAT has the same effect and semantic as EXPIRE,
118 /// but instead of specifying the number of seconds representing the TTL (time to live),
119 /// it takes an absolute Unix timestamp (seconds since January 1, 1970)
120 ///
121 /// A timestamp in the past will delete the key
122 ///
123 /// # Return
124 /// * `true` - if the timeout was set.
125 /// * `false` - if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments.
126 ///
127 /// # See Also
128 /// [<https://redis.io/commands/expireat/>](https://redis.io/commands/expireat/)
129 #[must_use]
130 fn expireat<K>(
131 &mut self,
132 key: K,
133 unix_time_seconds: u64,
134 option: ExpireOption,
135 ) -> PreparedCommand<Self, bool>
136 where
137 Self: Sized,
138 K: Into<CommandArg>,
139 {
140 prepare_command(
141 self,
142 cmd("EXPIREAT").arg(key).arg(unix_time_seconds).arg(option),
143 )
144 }
145
146 /// Returns the absolute Unix timestamp (since January 1, 1970) in seconds at which the given key will expire.
147 ///
148 /// # Return
149 /// Expiration Unix timestamp in seconds, or a negative value in order to signal an error (see the description below).
150 /// - The command returns -1 if the key exists but has no associated expiration time.
151 /// - The command returns -2 if the key does not exist.
152 ///
153 /// # See Also
154 /// [<https://redis.io/commands/expiretime/>](https://redis.io/commands/expiretime/)
155 #[must_use]
156 fn expiretime<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
157 where
158 Self: Sized,
159 K: Into<CommandArg>,
160 {
161 prepare_command(self, cmd("EXPIRETIME").arg(key))
162 }
163
164 /// Returns all keys matching pattern.
165 ///
166 /// # Return
167 /// list of keys matching pattern.
168 ///
169 /// # See Also
170 /// [<https://redis.io/commands/keys/>](https://redis.io/commands/keys/)
171 #[must_use]
172 fn keys<P, K, A>(&mut self, pattern: P) -> PreparedCommand<Self, A>
173 where
174 Self: Sized,
175 P: Into<CommandArg>,
176 K: FromValue,
177 A: FromSingleValueArray<K>,
178 {
179 prepare_command(self, cmd("KEYS").arg(pattern))
180 }
181
182 /// Atomically transfer a key or a collection of keys from a source Redis instance to a destination Redis instance.
183 ///
184 /// # Return
185 /// * `true` - on success
186 /// * `false` - if no keys were found in the source instance.
187 ///
188 /// # See Also
189 /// [<https://redis.io/commands/migrate/>](https://redis.io/commands/migrate/)
190 #[must_use]
191 fn migrate<H, K>(
192 &mut self,
193 host: H,
194 port: u16,
195 key: K,
196 destination_db: usize,
197 timeout: u64,
198 options: MigrateOptions,
199 ) -> PreparedCommand<Self, MigrateResult>
200 where
201 Self: Sized,
202 H: Into<CommandArg>,
203 K: Into<CommandArg>,
204 {
205 prepare_command(
206 self,
207 cmd("MIGRATE")
208 .arg(host)
209 .arg(port)
210 .arg(key)
211 .arg(destination_db)
212 .arg(timeout)
213 .arg(options),
214 )
215 }
216
217 /// Move key from the currently selected database to the specified destination database.
218 ///
219 /// # Return
220 /// * `true` - if key was moved.
221 /// * `false` - f key was not moved.
222 ///
223 /// # See Also
224 /// [<https://redis.io/commands/move/>](https://redis.io/commands/move/)
225 #[must_use]
226 fn move_<K>(&mut self, key: K, db: usize) -> PreparedCommand<Self, i64>
227 where
228 Self: Sized,
229 K: Into<CommandArg>,
230 {
231 prepare_command(self, cmd("MOVE").arg(key).arg(db))
232 }
233
234 /// Returns the internal encoding for the Redis object stored at `key`
235 ///
236 /// # Return
237 /// The encoding of the object, or nil if the key doesn't exist
238 ///
239 /// # See Also
240 /// [<https://redis.io/commands/object-encoding/>](https://redis.io/commands/object-encoding/)
241 #[must_use]
242 fn object_encoding<K, E>(&mut self, key: K) -> PreparedCommand<Self, E>
243 where
244 Self: Sized,
245 K: Into<CommandArg>,
246 E: FromValue,
247 {
248 prepare_command(self, cmd("OBJECT").arg("ENCODING").arg(key))
249 }
250
251 /// This command returns the logarithmic access frequency counter of a Redis object stored at `key`.
252 ///
253 /// # Return
254 /// The counter's value.
255 ///
256 /// # See Also
257 /// [<https://redis.io/commands/object-freq/>](https://redis.io/commands/object-freq/)
258 #[must_use]
259 fn object_freq<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
260 where
261 Self: Sized,
262 K: Into<CommandArg>,
263 {
264 prepare_command(self, cmd("OBJECT").arg("FREQ").arg(key))
265 }
266
267 /// This command returns the time in seconds since the last access to the value stored at `key`.
268 ///
269 /// # Return
270 /// The idle time in seconds.
271 ///
272 /// # See Also
273 /// [<https://redis.io/commands/object-idletime/>](https://redis.io/commands/object-idletime/)
274 #[must_use]
275 fn object_idle_time<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
276 where
277 Self: Sized,
278 K: Into<CommandArg>,
279 {
280 prepare_command(self, cmd("OBJECT").arg("IDLETIME").arg(key))
281 }
282
283 /// This command returns the reference count of the stored at `key`.
284 ///
285 /// # Return
286 /// The number of references.
287 ///
288 /// # See Also
289 /// [<https://redis.io/commands/object-refcount/>](https://redis.io/commands/object-refcount/)
290 #[must_use]
291 fn object_refcount<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
292 where
293 Self: Sized,
294 K: Into<CommandArg>,
295 {
296 prepare_command(self, cmd("OBJECT").arg("REFCOUNT").arg(key))
297 }
298
299 /// Remove the existing timeout on key,
300 /// turning the key from volatile (a key with an expire set)
301 /// to persistent (a key that will never expire as no timeout is associated).
302 ///
303 /// # Return
304 /// * `true` - if the timeout was removed.
305 /// * `false` - if key does not exist or does not have an associated timeout.
306 ///
307 /// # See Also
308 /// [<https://redis.io/commands/persist/>](https://redis.io/commands/persist/)
309 #[must_use]
310 fn persist<K>(&mut self, key: K) -> PreparedCommand<Self, bool>
311 where
312 Self: Sized,
313 K: Into<CommandArg>,
314 {
315 prepare_command(self, cmd("PERSIST").arg(key))
316 }
317
318 /// This command works exactly like EXPIRE but the time to live of the key is specified in milliseconds instead of seconds.
319 ///
320 /// # Return
321 /// * `true` - if the timeout was set.
322 /// * `false` - if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments.
323 ///
324 /// # See Also
325 /// [<https://redis.io/commands/pexpire/>](https://redis.io/commands/pexpire/)
326 #[must_use]
327 fn pexpire<K>(
328 &mut self,
329 key: K,
330 milliseconds: u64,
331 option: ExpireOption,
332 ) -> PreparedCommand<Self, bool>
333 where
334 Self: Sized,
335 K: Into<CommandArg>,
336 {
337 prepare_command(self, cmd("PEXPIRE").arg(key).arg(milliseconds).arg(option))
338 }
339
340 /// PEXPIREAT has the same effect and semantic as EXPIREAT,
341 /// but the Unix time at which the key will expire is specified in milliseconds instead of seconds.
342 ///
343 /// # Return
344 /// * `true` - if the timeout was set.
345 /// * `false` - if the timeout was not set. e.g. key doesn't exist, or operation skipped due to the provided arguments.
346 ///
347 /// # See Also
348 /// [<https://redis.io/commands/pexpireat/>](https://redis.io/commands/pexpireat/)
349 #[must_use]
350 fn pexpireat<K>(
351 &mut self,
352 key: K,
353 unix_time_milliseconds: u64,
354 option: ExpireOption,
355 ) -> PreparedCommand<Self, bool>
356 where
357 Self: Sized,
358 K: Into<CommandArg>,
359 {
360 prepare_command(
361 self,
362 cmd("PEXPIREAT")
363 .arg(key)
364 .arg(unix_time_milliseconds)
365 .arg(option),
366 )
367 }
368
369 /// PEXPIRETIME has the same semantic as EXPIRETIME,
370 /// but returns the absolute Unix expiration timestamp in milliseconds instead of seconds.
371 ///
372 /// # Return
373 /// Expiration Unix timestamp in milliseconds, or a negative value in order to signal an error (see the description below).
374 /// - The command returns -1 if the key exists but has no associated expiration time.
375 /// - The command returns -2 if the key does not exist.
376 ///
377 /// # See Also
378 /// [<https://redis.io/commands/pexpiretime/>](https://redis.io/commands/pexpiretime/)
379 #[must_use]
380 fn pexpiretime<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
381 where
382 Self: Sized,
383 K: Into<CommandArg>,
384 {
385 prepare_command(self, cmd("PEXPIRETIME").arg(key))
386 }
387
388 /// Returns the remaining time to live of a key that has a timeout.
389 ///
390 /// # Return
391 /// TTL in milliseconds, or a negative value in order to signal an error:
392 /// -2 if the key does not exist.
393 /// -1 if the key exists but has no associated expire.
394 ///
395 /// # See Also
396 /// [<https://redis.io/commands/pttl/>](https://redis.io/commands/pttl/)
397 #[must_use]
398 fn pttl<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
399 where
400 Self: Sized,
401 K: Into<CommandArg>,
402 {
403 prepare_command(self, cmd("PTTL").arg(key))
404 }
405
406 /// Return a random key from the currently selected database.
407 ///
408 /// # Return
409 /// The number of references.
410 ///
411 /// # See Also
412 /// [<https://redis.io/commands/randomkey/>](https://redis.io/commands/randomkey/)
413 #[must_use]
414 fn randomkey<R>(&mut self) -> PreparedCommand<Self, R>
415 where
416 Self: Sized,
417 R: FromValue,
418 {
419 prepare_command(self, cmd("RANDOMKEY"))
420 }
421
422 /// Renames key to newkey.
423 ///
424 /// # See Also
425 /// [<https://redis.io/commands/rename/>](https://redis.io/commands/rename/)
426 #[must_use]
427 fn rename<K1, K2>(&mut self, key: K1, new_key: K2) -> PreparedCommand<Self, ()>
428 where
429 Self: Sized,
430 K1: Into<CommandArg>,
431 K2: Into<CommandArg>,
432 {
433 prepare_command(self, cmd("RENAME").arg(key).arg(new_key))
434 }
435
436 /// Renames key to newkey if newkey does not yet exist.
437 /// It returns an error when key does not exist.
438 ///
439 /// # Return
440 /// * `true` if key was renamed to newkey.
441 /// * `false` if newkey already exists.
442 /// # See Also
443 /// [<https://redis.io/commands/renamenx/>](https://redis.io/commands/renamenx/)
444 #[must_use]
445 fn renamenx<K1, K2>(&mut self, key: K1, new_key: K2) -> PreparedCommand<Self, bool>
446 where
447 Self: Sized,
448 K1: Into<CommandArg>,
449 K2: Into<CommandArg>,
450 {
451 prepare_command(self, cmd("RENAMENX").arg(key).arg(new_key))
452 }
453
454 /// Create a key associated with a value that is obtained by deserializing
455 /// the provided serialized value (obtained via DUMP).
456 ///
457 /// # Return
458 /// Restore command builder
459 ///
460 /// # See Also
461 /// [<https://redis.io/commands/restore/>](https://redis.io/commands/restore/)
462 #[must_use]
463 fn restore<K>(
464 &mut self,
465 key: K,
466 ttl: u64,
467 serialized_value: Vec<u8>,
468 options: RestoreOptions,
469 ) -> PreparedCommand<Self, ()>
470 where
471 Self: Sized,
472 K: Into<CommandArg>,
473 {
474 prepare_command(
475 self,
476 cmd("RESTORE")
477 .arg(key)
478 .arg(ttl)
479 .arg(CommandArg::Binary(serialized_value))
480 .arg(options),
481 )
482 }
483
484 /// Iterates the set of keys in the currently selected Redis database.
485 ///
486 /// # Return
487 /// A list of keys
488 ///
489 /// # See Also
490 /// [<https://redis.io/commands/scan/>](https://redis.io/commands/scan/)
491 #[must_use]
492 fn scan<K, A>(&mut self, cursor: u64, options: ScanOptions) -> PreparedCommand<Self, (u64, A)>
493 where
494 Self: Sized,
495 K: FromValue,
496 A: FromSingleValueArray<K>,
497 {
498 prepare_command(self, cmd("SCAN").arg(cursor).arg(options))
499 }
500
501 /// Returns the elements contained in the list, set or sorted set at key.
502 ///
503 /// # Return
504 /// A collection of sorted elements.
505 ///
506 /// # See Also
507 /// [<https://redis.io/commands/sort/>](https://redis.io/commands/sort/)
508 #[must_use]
509 fn sort<K, M, A>(&mut self, key: K, options: SortOptions) -> PreparedCommand<Self, A>
510 where
511 Self: Sized,
512 K: Into<CommandArg>,
513 M: FromValue,
514 A: FromSingleValueArray<M>,
515 {
516 prepare_command(self, cmd("SORT").arg(key).arg(options))
517 }
518
519 /// Stores the elements contained in the list, set or sorted set at key.
520 ///
521 /// # Return
522 /// The number of sorted elements in the destination list.
523 ///
524 /// # See Also
525 /// [<https://redis.io/commands/sort/>](https://redis.io/commands/sort/)
526 #[must_use]
527 fn sort_and_store<K, D>(
528 &mut self,
529 key: K,
530 destination: D,
531 options: SortOptions,
532 ) -> PreparedCommand<Self, usize>
533 where
534 Self: Sized,
535 K: Into<CommandArg>,
536 D: Into<CommandArg>,
537 {
538 prepare_command(
539 self,
540 cmd("SORT")
541 .arg(key)
542 .arg(options)
543 .arg("STORE")
544 .arg(destination),
545 )
546 }
547
548 /// Read-only variant of the SORT command.
549 ///
550 /// It is exactly like the original SORT but refuses the STORE option
551 /// and can safely be used in read-only replicas.
552 ///
553 /// # Return
554 /// A collection of sorted elements.
555 ///
556 /// # See Also
557 /// [<https://redis.io/commands/sort_ro/>](https://redis.io/commands/sort_ro/)
558 #[must_use]
559 fn sort_readonly<K, M, A>(&mut self, key: K, options: SortOptions) -> PreparedCommand<Self, A>
560 where
561 Self: Sized,
562 K: Into<CommandArg>,
563 M: FromValue,
564 A: FromSingleValueArray<M>,
565 {
566 prepare_command(self, cmd("SORT_RO").arg(key).arg(options))
567 }
568
569 /// Alters the last access time of a key(s). A key is ignored if it does not exist.
570 ///
571 /// # Return
572 /// The number of keys that were touched.
573 ///
574 /// # See Also
575 /// [<https://redis.io/commands/touch/>](https://redis.io/commands/touch/)
576 #[must_use]
577 fn touch<K, KK>(&mut self, keys: KK) -> PreparedCommand<Self, usize>
578 where
579 Self: Sized,
580 K: Into<CommandArg>,
581 KK: SingleArgOrCollection<K>,
582 {
583 prepare_command(self, cmd("TOUCH").arg(keys))
584 }
585
586 /// Returns the remaining time to live of a key that has a timeout.
587 ///
588 /// # Return
589 /// TTL in seconds, or a negative value in order to signal an error:
590 /// -2 if the key does not exist.
591 /// -1 if the key exists but has no associated expire.
592 ///
593 /// # See Also
594 /// [<https://redis.io/commands/ttl/>](https://redis.io/commands/ttl/)
595 #[must_use]
596 fn ttl<K>(&mut self, key: K) -> PreparedCommand<Self, i64>
597 where
598 Self: Sized,
599 K: Into<CommandArg>,
600 {
601 prepare_command(self, cmd("TTL").arg(key))
602 }
603
604 /// Returns the string representation of the type of the value stored at key.
605 ///
606 /// The different types that can be returned are: string, list, set, zset, hash and stream.
607 ///
608 /// # Return
609 /// type of key, or empty string when key does not exist.
610 ///
611 /// # See Also
612 /// [<https://redis.io/commands/type/>](https://redis.io/commands/type/)
613 #[must_use]
614 fn type_<K>(&mut self, key: K) -> PreparedCommand<Self, String>
615 where
616 Self: Sized,
617 K: Into<CommandArg>,
618 {
619 prepare_command(self, cmd("TYPE").arg(key))
620 }
621
622 /// This command is very similar to DEL: it removes the specified keys.
623 ///
624 /// # Return
625 /// The number of keys that were unlinked.
626 ///
627 /// # See Also
628 /// [<https://redis.io/commands/unlink/>](https://redis.io/commands/unlink/)
629 #[must_use]
630 fn unlink<K, C>(&mut self, keys: C) -> PreparedCommand<Self, usize>
631 where
632 Self: Sized,
633 K: Into<CommandArg>,
634 C: SingleArgOrCollection<K>,
635 {
636 prepare_command(self, cmd("UNLINK").arg(keys))
637 }
638
639 /// This command blocks the current client until all the previous write commands are
640 /// successfully transferred and acknowledged by at least the specified number of replicas.
641 ///
642 /// # Return
643 /// The number of replicas reached by all the writes performed in the context of the current connection.
644 ///
645 /// # See Also
646 /// [<https://redis.io/commands/wait/>](https://redis.io/commands/wait/)
647 #[must_use]
648 fn wait(&mut self, num_replicas: usize, timeout: u64) -> PreparedCommand<Self, usize>
649 where
650 Self: Sized,
651 {
652 prepare_command(self, cmd("WAIT").arg(num_replicas).arg(timeout))
653 }
654}
655
656/// Options for the [`expire`](crate::GenericCommands::expire) command
657pub enum ExpireOption {
658 /// No option
659 None,
660 /// Set expiry only when the key has no expiry
661 Nx,
662 /// Set expiry only when the key has no expiry
663 Xx,
664 /// Set expiry only when the new expiry is greater than current one
665 Gt,
666 /// Set expiry only when the new expiry is less than current one
667 Lt,
668}
669
670impl Default for ExpireOption {
671 fn default() -> Self {
672 ExpireOption::None
673 }
674}
675
676impl IntoArgs for ExpireOption {
677 fn into_args(self, args: CommandArgs) -> CommandArgs {
678 match self {
679 ExpireOption::None => args,
680 ExpireOption::Nx => args.arg("NX"),
681 ExpireOption::Xx => args.arg("XX"),
682 ExpireOption::Gt => args.arg("GT"),
683 ExpireOption::Lt => args.arg("LT"),
684 }
685 }
686}
687
688#[derive(Default)]
689pub struct MigrateOptions {
690 command_args: CommandArgs,
691}
692
693impl MigrateOptions {
694 #[must_use]
695 pub fn copy(self) -> Self {
696 Self {
697 command_args: self.command_args.arg("COPY"),
698 }
699 }
700
701 #[must_use]
702 pub fn replace(self) -> Self {
703 Self {
704 command_args: self.command_args.arg("REPLACE"),
705 }
706 }
707
708 #[must_use]
709 pub fn auth<P: Into<CommandArg>>(self, password: P) -> Self {
710 Self {
711 command_args: self.command_args.arg("AUTH").arg(password),
712 }
713 }
714
715 #[must_use]
716 pub fn auth2<U: Into<CommandArg>, P: Into<CommandArg>>(self, username: U, password: P) -> Self {
717 Self {
718 command_args: self.command_args.arg("AUTH2").arg(username).arg(password),
719 }
720 }
721
722 #[must_use]
723 pub fn keys<K: Into<CommandArg>, KK: SingleArgOrCollection<K>>(self, keys: KK) -> Self {
724 Self {
725 command_args: self.command_args.arg("KEYS").arg(keys),
726 }
727 }
728}
729
730impl IntoArgs for MigrateOptions {
731 fn into_args(self, args: CommandArgs) -> CommandArgs {
732 args.arg(self.command_args)
733 }
734}
735
736/// Options for the [`restore`](crate::GenericCommands::restore) command
737#[derive(Default)]
738pub struct RestoreOptions {
739 command_args: CommandArgs,
740}
741
742impl RestoreOptions {
743 #[must_use]
744 pub fn replace(self) -> Self {
745 Self {
746 command_args: self.command_args.arg("REPLACE"),
747 }
748 }
749
750 #[must_use]
751 pub fn abs_ttl(self) -> Self {
752 Self {
753 command_args: self.command_args.arg("ABSTTL"),
754 }
755 }
756
757 #[must_use]
758 pub fn idle_time(self, idle_time: i64) -> Self {
759 Self {
760 command_args: self.command_args.arg("IDLETIME").arg(idle_time),
761 }
762 }
763
764 #[must_use]
765 pub fn frequency(self, frequency: f64) -> Self {
766 Self {
767 command_args: self.command_args.arg("FREQ").arg(frequency),
768 }
769 }
770}
771
772impl IntoArgs for RestoreOptions {
773 fn into_args(self, args: CommandArgs) -> CommandArgs {
774 args.arg(self.command_args)
775 }
776}
777
778/// Order option of the [`sort`](crate::GenericCommands::sort) command
779pub enum SortOrder {
780 Asc,
781 Desc,
782}
783
784impl IntoArgs for SortOrder {
785 fn into_args(self, args: CommandArgs) -> CommandArgs {
786 match self {
787 SortOrder::Asc => args.arg("ASC"),
788 SortOrder::Desc => args.arg("DESC"),
789 }
790 }
791}
792
793/// Options for the [`sort`](crate::GenericCommands::sort) command
794#[derive(Default)]
795pub struct SortOptions {
796 command_args: CommandArgs,
797}
798
799impl SortOptions {
800 #[must_use]
801 pub fn by<P: Into<CommandArg>>(self, pattern: P) -> Self {
802 Self {
803 command_args: self.command_args.arg("BY").arg(pattern),
804 }
805 }
806
807 #[must_use]
808 pub fn limit(self, offset: usize, count: isize) -> Self {
809 Self {
810 command_args: self.command_args.arg("LIMIT").arg(offset).arg(count),
811 }
812 }
813
814 #[must_use]
815 pub fn get<P: Into<CommandArg>>(self, pattern: P) -> Self {
816 Self {
817 command_args: self.command_args.arg("GET").arg(pattern),
818 }
819 }
820
821 #[must_use]
822 pub fn order(self, order: SortOrder) -> Self {
823 Self {
824 command_args: self.command_args.arg(order),
825 }
826 }
827
828 #[must_use]
829 pub fn alpha(self) -> Self {
830 Self {
831 command_args: self.command_args.arg("ALPHA"),
832 }
833 }
834}
835
836impl IntoArgs for SortOptions {
837 fn into_args(self, args: CommandArgs) -> CommandArgs {
838 args.arg(self.command_args)
839 }
840}
841
842/// Result for the [`dump`](crate::GenericCommands::dump) command.
843pub struct DumpResult {
844 pub serialized_value: Vec<u8>,
845}
846
847impl FromValue for DumpResult {
848 fn from_value(value: Value) -> crate::Result<Self> {
849 match value {
850 Value::BulkString(Some(b)) => Ok(DumpResult {
851 serialized_value: b,
852 }),
853 _ => Err(Error::Client("Unexpected dump format".to_owned())),
854 }
855 }
856}
857
858/// Options for the [`scan`](crate::GenericCommands::scan) command
859#[derive(Default)]
860pub struct ScanOptions {
861 command_args: CommandArgs,
862}
863
864impl ScanOptions {
865 #[must_use]
866 pub fn match_pattern<P: Into<CommandArg>>(self, match_pattern: P) -> Self {
867 Self {
868 command_args: self.command_args.arg("MATCH").arg(match_pattern),
869 }
870 }
871
872 #[must_use]
873 pub fn count(self, count: usize) -> Self {
874 Self {
875 command_args: self.command_args.arg("COUNT").arg(count),
876 }
877 }
878
879 #[must_use]
880 pub fn type_<TY: Into<CommandArg>>(self, type_: TY) -> Self {
881 Self {
882 command_args: self.command_args.arg("TYPE").arg(type_),
883 }
884 }
885}
886
887impl IntoArgs for ScanOptions {
888 fn into_args(self, args: CommandArgs) -> CommandArgs {
889 args.arg(self.command_args)
890 }
891}
892
893/// Result for the [`migrate`](crate::GenericCommands::migrate) command
894pub enum MigrateResult {
895 /// key(s) successfully migrated
896 Ok,
897 /// no keys were found in the source instance.
898 NoKey,
899}
900
901impl FromValue for MigrateResult {
902 fn from_value(value: Value) -> Result<Self> {
903 let result: String = value.into()?;
904 match result.as_str() {
905 "OK" => Ok(Self::Ok),
906 "NOKEY" => Ok(Self::NoKey),
907 _ => Err(Error::Client(
908 "Unexpected result for command 'MIGRATE'".to_owned(),
909 )),
910 }
911 }
912}