rustis/commands/hash_commands.rs
1use crate::{
2 client::{PreparedCommand, prepare_command},
3 commands::{ExpireOption, GetExOptions, SetExpiration},
4 resp::{Args, CommandArgs, Response, cmd, deserialize_vec_of_pairs},
5};
6use serde::{Deserialize, de::DeserializeOwned};
7
8/// A group of Redis commands related to [`Hashes`](https://redis.io/docs/data-types/hashes/)
9///
10/// # See Also
11/// [Redis Hash Commands](https://redis.io/commands/?group=hash)
12pub trait HashCommands<'a>: Sized {
13 /// Removes the specified fields from the hash stored at key.
14 ///
15 /// # Return
16 /// the number of fields that were removed from the hash, not including specified but non existing fields.
17 ///
18 /// # See Also
19 /// [<https://redis.io/commands/hdel/>](https://redis.io/commands/hdel/)
20 #[must_use]
21 fn hdel(self, key: impl Args, fields: impl Args) -> PreparedCommand<'a, Self, usize> {
22 prepare_command(self, cmd("HDEL").arg(key).arg(fields))
23 }
24
25 /// Returns if field is an existing field in the hash stored at key.
26 ///
27 /// # Return
28 /// * `true` - if the hash contains field.
29 /// * `false` - if the hash does not contain field, or key does not exist.
30 ///
31 /// # See Also
32 /// [<https://redis.io/commands/hexists/>](https://redis.io/commands/hexists/)
33 #[must_use]
34 fn hexists(self, key: impl Args, field: impl Args) -> PreparedCommand<'a, Self, bool> {
35 prepare_command(self, cmd("HEXISTS").arg(key).arg(field))
36 }
37
38 /// Set an expiration (TTL or time to live) on one or more fields of a given hash key.
39 ///
40 /// Field(s) will automatically be deleted from the hash key when their TTLs expire.
41 ///
42 /// # Arguments
43 /// * `key` - The hash key
44 /// * `seconds ` - The expiration time in seconds
45 /// * `option` - The [`ExpireOption`](crate::commands::ExpireOption) option.
46 /// * `fields` - The fields to expire.
47 ///
48 /// # Return
49 /// For each field:
50 /// * `-2` - if no such field exists in the provided hash key, or the provided key does not exist.
51 /// * `0` - if the specified NX | XX | GT | LT condition has not been met.
52 /// * `1` - if the expiration time was set/updated.
53 /// * `2` - when the command is called with 0 seconds.
54 ///
55 /// # See Also
56 /// [<https://redis.io/commands/hexpire/>](https://redis.io/commands/hexpire/)
57 #[must_use]
58 fn hexpire<R: Response>(
59 self,
60 key: impl Args,
61 seconds: u64,
62 option: ExpireOption,
63 fields: impl Args,
64 ) -> PreparedCommand<'a, Self, R> {
65 prepare_command(
66 self,
67 cmd("HEXPIRE")
68 .arg(key)
69 .arg(seconds)
70 .arg(option)
71 .arg("FIELDS")
72 .arg(fields.num_args())
73 .arg(fields),
74 )
75 }
76
77 /// HEXPIREAT has the same effect and semantics as HEXPIRE,
78 /// but instead of specifying the number of seconds for the TTL (time to live),
79 /// it takes an absolute Unix timestamp in seconds since Unix epoch.
80 ///
81 /// A timestamp in the past will delete the field immediately.
82 ///
83 /// # Arguments
84 /// * `key` - The hash key
85 /// * `unix_time_seconds ` - The aboslute unix timestamp the fields will expire at.
86 /// * `option` - The [`ExpireOption`](crate::commands::ExpireOption) option.
87 /// * `fields` - The fields to expire.
88 ///
89 /// # Return
90 /// For each field:
91 /// * `-2` - if no such field exists in the provided hash key, or the provided key does not exist.
92 /// * `0` - if the specified NX | XX | GT | LT condition has not been met.
93 /// * `1` - if the expiration time was set/updated.
94 /// * `2` - when the command is called with a past Unix time in seconds.
95 ///
96 /// # See Also
97 /// [<https://redis.io/commands/hexpireat/>](https://redis.io/commands/hexpireat/)
98 #[must_use]
99 fn hexpireat<R: Response>(
100 self,
101 key: impl Args,
102 unix_time_seconds: u64,
103 option: ExpireOption,
104 fields: impl Args,
105 ) -> PreparedCommand<'a, Self, R> {
106 prepare_command(
107 self,
108 cmd("HEXPIREAT")
109 .arg(key)
110 .arg(unix_time_seconds)
111 .arg(option)
112 .arg("FIELDS")
113 .arg(fields.num_args())
114 .arg(fields),
115 )
116 }
117
118 /// Returns the absolute Unix timestamp in seconds since Unix epoch
119 /// at which the given key's field(s) will expire.
120 ///
121 /// # Arguments
122 /// * `key` - The hash key
123 /// * `fields` - The fields to get the expiration time from.
124 ///
125 /// # Return
126 /// For each field, the expiration (Unix timestamp) in seconds.
127 /// - The command returns -2 if no such field exists in the provided hash key, or the provided key does not exist.
128 /// - The command returns -1 if the field exists but has no associated expiration set.
129 ///
130 /// # See Also
131 /// [<https://redis.io/commands/hexpiretime/>](https://redis.io/commands/hexpiretime/)
132 #[must_use]
133 fn hexpiretime<R: Response>(
134 self,
135 key: impl Args,
136 fields: impl Args,
137 ) -> PreparedCommand<'a, Self, R> {
138 prepare_command(
139 self,
140 cmd("HEXPIRETIME")
141 .arg(key)
142 .arg("FIELDS")
143 .arg(fields.num_args())
144 .arg(fields),
145 )
146 }
147
148 /// Returns the value associated with field in the hash stored at key.
149 ///
150 /// # Return
151 /// The value associated with field, or nil when field is not present in the hash or key does not exist.
152 ///
153 /// # See Also
154 /// [<https://redis.io/commands/hget/>](https://redis.io/commands/hget/)
155 #[must_use]
156 fn hget<R: Response>(self, key: impl Args, field: impl Args) -> PreparedCommand<'a, Self, R> {
157 prepare_command(self, cmd("HGET").arg(key).arg(field))
158 }
159
160 /// Returns all fields and values of the hash stored at key.
161 ///
162 /// # Return
163 /// The list of fields and their values stored in the hash, or an empty list when key does not exist.
164 ///
165 /// # See Also
166 /// [<https://redis.io/commands/hgetall/>](https://redis.io/commands/hgetall/)
167 #[must_use]
168 fn hgetall<R: Response>(self, key: impl Args) -> PreparedCommand<'a, Self, R> {
169 prepare_command(self, cmd("HGETALL").arg(key))
170 }
171
172 /// Get and delete the value of one or more fields of a given hash key.
173 ///
174 /// When the last field is deleted, the key will also be deleted.
175 ///
176 /// # Arguments
177 /// * `key` - The hash key
178 /// * `fields` - The fields to get and delete.
179 ///
180 /// # Return
181 /// A list of deleted fields and their values or nil for fields that do not exist.
182 ///
183 /// # See Also
184 /// [<https://redis.io/commands/hgetdel/>](https://redis.io/commands/hgetdel/)
185 #[must_use]
186 fn hgetdel<R: Response>(
187 self,
188 key: impl Args,
189 fields: impl Args,
190 ) -> PreparedCommand<'a, Self, R> {
191 prepare_command(
192 self,
193 cmd("HGETDEL")
194 .arg(key)
195 .arg("FIELDS")
196 .arg(fields.num_args())
197 .arg(fields),
198 )
199 }
200
201 /// Get the value of one or more fields of a given hash key
202 /// and optionally set their expiration time or time-to-live (TTL).
203 ///
204 /// # Arguments
205 /// * `key` - The hash key
206 /// * `options` - The [`GetExOptions`](crate::commands::GetExOptions) options.
207 /// * `fields` - The fields to get.
208 ///
209 /// # Return
210 /// a list of values associated with the given fields, in the same order as they are requested.
211 ///
212 /// # See Also
213 /// [<https://redis.io/commands/hgetex/>](https://redis.io/commands/hgetex/)
214 #[must_use]
215 fn hgetex<R: Response>(
216 self,
217 key: impl Args,
218 options: GetExOptions,
219 fields: impl Args,
220 ) -> PreparedCommand<'a, Self, R> {
221 prepare_command(
222 self,
223 cmd("HGETEX")
224 .arg(key)
225 .arg(options)
226 .arg("FIELDS")
227 .arg(fields.num_args())
228 .arg(fields),
229 )
230 }
231
232 /// Increments the number stored at field in the hash stored at key by increment.
233 ///
234 /// # Return
235 /// The value at field after the increment operation.
236 ///
237 /// # See Also
238 /// [<https://redis.io/commands/hincrby/>](https://redis.io/commands/hincrby/)
239 #[must_use]
240 fn hincrby(
241 self,
242 key: impl Args,
243 field: impl Args,
244 increment: i64,
245 ) -> PreparedCommand<'a, Self, i64> {
246 prepare_command(self, cmd("HINCRBY").arg(key).arg(field).arg(increment))
247 }
248
249 /// Increment the specified field of a hash stored at key,
250 /// and representing a floating point number, by the specified increment.
251 ///
252 /// # Return
253 /// The value at field after the increment operation.
254 ///
255 /// # See Also
256 /// [<https://redis.io/commands/hincrbyfloat/>](https://redis.io/commands/hincrbyfloat/)
257 #[must_use]
258 fn hincrbyfloat(
259 self,
260 key: impl Args,
261 field: impl Args,
262 increment: f64,
263 ) -> PreparedCommand<'a, Self, f64> {
264 prepare_command(self, cmd("HINCRBYFLOAT").arg(key).arg(field).arg(increment))
265 }
266
267 /// Returns all field names in the hash stored at key.
268 ///
269 /// # Return
270 /// The list of fields in the hash, or an empty list when key does not exist.
271 ///
272 /// # See Also
273 /// [<https://redis.io/commands/hkeys/>](https://redis.io/commands/hkeys/)
274 #[must_use]
275 fn hkeys<R: Response>(self, key: impl Args) -> PreparedCommand<'a, Self, R> {
276 prepare_command(self, cmd("HKEYS").arg(key))
277 }
278
279 /// Returns the number of fields contained in the hash stored at key.
280 ///
281 /// # Return
282 /// The number of fields in the hash, or 0 when key does not exist.
283 ///
284 /// # See Also
285 /// [<https://redis.io/commands/hlen/>](https://redis.io/commands/hlen/)
286 #[must_use]
287 fn hlen(self, key: impl Args) -> PreparedCommand<'a, Self, usize> {
288 prepare_command(self, cmd("HLEN").arg(key))
289 }
290
291 /// Returns the values associated with the specified fields in the hash stored at key.
292 ///
293 /// # Return
294 /// The list of values associated with the given fields, in the same order as they are requested.
295 ///
296 /// # See Also
297 /// [<https://redis.io/commands/hmget/>](https://redis.io/commands/hmget/)
298 #[must_use]
299 fn hmget<R: Response>(self, key: impl Args, fields: impl Args) -> PreparedCommand<'a, Self, R> {
300 prepare_command(self, cmd("HMGET").arg(key).arg(fields))
301 }
302
303 /// Remove the existing expiration on a hash key's field(s),
304 /// turning the field(s) from volatile (a field with expiration set)
305 /// to persistent (a field that will never expire as no TTL (time to live) is associated).
306 ///
307 /// # Return
308 /// For each field:
309 /// * `-2` - if no such field exists in the provided hash key, or the provided key does not exist.
310 /// * `-1` - if the field exists but has no associated expiration set.
311 /// * `1` - the expiration was removed.
312 ///
313 /// # See Also
314 /// [<https://redis.io/commands/hpersist/>](https://redis.io/commands/hpersist/)
315 #[must_use]
316 fn hpersist<R: Response>(
317 self,
318 key: impl Args,
319 fields: impl Args,
320 ) -> PreparedCommand<'a, Self, R> {
321 prepare_command(self, cmd("HPERSIST").arg(key).arg(fields))
322 }
323
324 /// This command works like [`hexpire`](HashCommands::hexpire), but the expiration of a field is specified in milliseconds instead of seconds.
325 ///
326 /// # Arguments
327 /// * `key` - The hash key
328 /// * `milliseconds ` - The expiration time in milliseconds
329 /// * `option` - The [`ExpireOption`](crate::commands::ExpireOption) option.
330 /// * `fields` - The fields to expire.
331 ///
332 /// # Return
333 /// For each field:
334 /// * `-2` - if no such field exists in the provided hash key, or the provided key does not exist.
335 /// * `0` - if the specified NX | XX | GT | LT condition has not been met.
336 /// * `1` - if the expiration time was set/updated.
337 /// * `2` - when the command is called with 0 milliseconds.
338 ///
339 /// # See Also
340 /// [<https://redis.io/commands/hpexpire/>](https://redis.io/commands/hpexpire/)
341 #[must_use]
342 fn hpexpire<R: Response>(
343 self,
344 key: impl Args,
345 milliseconds: u64,
346 option: ExpireOption,
347 fields: impl Args,
348 ) -> PreparedCommand<'a, Self, R> {
349 prepare_command(
350 self,
351 cmd("HPEXPIRE")
352 .arg(key)
353 .arg(milliseconds)
354 .arg(option)
355 .arg("FIELDS")
356 .arg(fields.num_args())
357 .arg(fields),
358 )
359 }
360
361 /// This command has the same effect and semantics as [`hexpireat`](HashCommands::hexpireat),
362 /// but the Unix time at which the field will expire
363 /// is specified in milliseconds since Unix epoch instead of seconds.
364 ///
365 /// # Arguments
366 /// * `key` - The hash key
367 /// * `unix_time_milliseconds` - The aboslute unix timestamp in milliseconds, the fields will expire at.
368 /// * `option` - The [`ExpireOption`](crate::commands::ExpireOption) option.
369 /// * `fields` - The fields to expire.
370 ///
371 /// # Return
372 /// For each field:
373 /// * `-2` - if no such field exists in the provided hash key, or the provided key does not exist.
374 /// * `0` - if the specified NX | XX | GT | LT condition has not been met.
375 /// * `1` - if the expiration time was set/updated.
376 /// * `2` - when the command is called with a past Unix time in milliseconds.
377 ///
378 /// # See Also
379 /// [<https://redis.io/commands/hpexpireat/>](https://redis.io/commands/hpexpireat/)
380 #[must_use]
381 fn hpexpireat<R: Response>(
382 self,
383 key: impl Args,
384 unix_time_milliseconds: u64,
385 option: ExpireOption,
386 fields: impl Args,
387 ) -> PreparedCommand<'a, Self, R> {
388 prepare_command(
389 self,
390 cmd("HPEXPIREAT")
391 .arg(key)
392 .arg(unix_time_milliseconds)
393 .arg(option)
394 .arg("FIELDS")
395 .arg(fields.num_args())
396 .arg(fields),
397 )
398 }
399
400 /// This command has the same semantics as [`hexpiretime`](HashCommands::hexpiretime),
401 /// but returns the absolute Unix expiration timestamp
402 /// in milliseconds since Unix epoch instead of seconds.
403 ///
404 /// # Arguments
405 /// * `key` - The hash key
406 /// * `fields` - The fields to get the expiration time from.
407 ///
408 /// # Return
409 /// For each field, the expiration (Unix timestamp) in milliseconds.
410 /// - The command returns -2 if no such field exists in the provided hash key, or the provided key does not exist.
411 /// - The command returns -1 if the field exists but has no associated expiration set.
412 ///
413 /// # See Also
414 /// [<https://redis.io/commands/hpexpiretime/>](https://redis.io/commands/hpexpiretime/)
415 #[must_use]
416 fn hpexpiretime<R: Response>(
417 self,
418 key: impl Args,
419 fields: impl Args,
420 ) -> PreparedCommand<'a, Self, R> {
421 prepare_command(
422 self,
423 cmd("HPEXPIRETIME")
424 .arg(key)
425 .arg("FIELDS")
426 .arg(fields.num_args())
427 .arg(fields),
428 )
429 }
430
431 /// Like [`httl`](HashCommands::httl), this command returns the remaining TTL (time to live)
432 /// of a field that has an expiration set, but in milliseconds instead of seconds.
433 ///
434 /// # Arguments
435 /// * `key` - The hash key
436 /// * `fields` - The fields to get the TTL from.
437 ///
438 /// # Return
439 /// the TTL in milliseconds.
440 /// - The command returns -2 if no such field exists in the provided hash key, or the provided key does not exist.
441 /// - The command returns -1 if the field exists but has no associated expiration set.
442 ///
443 /// # See Also
444 /// [<https://redis.io/commands/hpttl/>](https://redis.io/commands/hpttl/)
445 #[must_use]
446 fn hpttl<R: Response>(self, key: impl Args, fields: impl Args) -> PreparedCommand<'a, Self, R> {
447 prepare_command(
448 self,
449 cmd("HPTTL")
450 .arg(key)
451 .arg("FIELDS")
452 .arg(fields.num_args())
453 .arg(fields),
454 )
455 }
456
457 /// return random fields from the hash value stored at key.
458 ///
459 /// # Return
460 /// * When called with just the key argument, return a random field from the hash value stored at key.
461 ///
462 /// # See Also
463 /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
464 #[must_use]
465 fn hrandfield<R: Response>(self, key: impl Args) -> PreparedCommand<'a, Self, R> {
466 prepare_command(self, cmd("HRANDFIELD").arg(key))
467 }
468
469 /// return random fields from the hash value stored at key.
470 ///
471 /// # Return
472 /// * If the provided count argument is positive, return an array of distinct fields.
473 /// The array's length is either count or the hash's number of fields (HLEN), whichever is lower.
474 /// * If called with a negative count, the behavior changes and the command is allowed to return the same field multiple times.
475 /// In this case, the number of returned fields is the absolute value of the specified count.
476 ///
477 /// # See Also
478 /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
479 #[must_use]
480 fn hrandfields<R: Response>(
481 self,
482 key: impl Args,
483 count: isize,
484 ) -> PreparedCommand<'a, Self, R> {
485 prepare_command(self, cmd("HRANDFIELD").arg(key).arg(count))
486 }
487
488 /// return random fields from the hash value stored at key.
489 ///
490 /// # Return
491 /// * If the provided count argument is positive, return an array of distinct fields.
492 /// The array's length is either count or the hash's number of fields (HLEN), whichever is lower.
493 /// * If called with a negative count, the behavior changes and the command is allowed to return the same field multiple times.
494 /// In this case, the number of returned fields is the absolute value of the specified count.
495 /// The optional WITHVALUES modifier changes the reply so it includes the respective values of the randomly selected hash fields.
496 ///
497 /// # See Also
498 /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
499 #[must_use]
500 fn hrandfields_with_values<R: Response>(
501 self,
502 key: impl Args,
503 count: isize,
504 ) -> PreparedCommand<'a, Self, R> {
505 prepare_command(
506 self,
507 cmd("HRANDFIELD").arg(key).arg(count).arg("WITHVALUES"),
508 )
509 }
510
511 /// Iterates fields of Hash types and their associated values.
512 ///
513 /// # Return
514 /// array of elements contain two elements, a field and a value,
515 /// for every returned element of the Hash.
516 ///
517 /// # See Also
518 /// [<https://redis.io/commands/hlen/>](https://redis.io/commands/hscan/)
519 #[must_use]
520 fn hscan<F: Response + DeserializeOwned, V: Response + DeserializeOwned>(
521 self,
522 key: impl Args,
523 cursor: u64,
524 options: HScanOptions,
525 ) -> PreparedCommand<'a, Self, HScanResult<F, V>> {
526 prepare_command(self, cmd("HSCAN").arg(key).arg(cursor).arg(options))
527 }
528
529 /// Sets field in the hash stored at key to value.
530 ///
531 /// # Return
532 /// The number of fields that were added.
533 ///
534 /// # See Also
535 /// [<https://redis.io/commands/hset/>](https://redis.io/commands/hset/)
536 #[must_use]
537 fn hset(self, key: impl Args, items: impl Args) -> PreparedCommand<'a, Self, usize> {
538 prepare_command(self, cmd("HSET").arg(key).arg(items))
539 }
540
541 /// Set the value of one or more fields of a given hash key,
542 /// and optionally set their expiration time or time-to-live (TTL).
543 ///
544 /// # Return
545 /// * `true` if all the fields wereset.
546 /// * `false` if no fields were set.
547 ///
548 /// # See Also
549 /// [<https://redis.io/commands/hsetex/>](https://redis.io/commands/hsetex/)
550 #[must_use]
551 fn hsetex(
552 self,
553 key: impl Args,
554 condition: HSetExCondition,
555 expiration: SetExpiration,
556 keep_ttl: bool,
557 items: impl Args,
558 ) -> PreparedCommand<'a, Self, bool> {
559 prepare_command(
560 self,
561 cmd("HSETEX")
562 .arg(key)
563 .arg(condition)
564 .arg(expiration)
565 .arg_if(keep_ttl, "KEEPTTL")
566 .arg("FIELDS")
567 .arg(items.num_args() / 2)
568 .arg(items),
569 )
570 }
571
572 /// Sets field in the hash stored at key to value, only if field does not yet exist.
573 ///
574 /// # Return
575 /// * `true` - if field is a new field in the hash and value was set.
576 /// * `false` - if field already exists in the hash and no operation was performed.
577 ///
578 /// # See Also
579 /// [<https://redis.io/commands/hsetnx/>](https://redis.io/commands/hsetnx/)
580 #[must_use]
581 fn hsetnx(
582 self,
583 key: impl Args,
584 field: impl Args,
585 value: impl Args,
586 ) -> PreparedCommand<'a, Self, bool> {
587 prepare_command(self, cmd("HSETNX").arg(key).arg(field).arg(value))
588 }
589
590 /// Returns the string length of the value associated with field in the hash stored at key.
591 ///
592 /// # Return
593 /// the string length of the value associated with field,
594 /// or zero when field is not present in the hash or key does not exist at all.
595 ///
596 /// # See Also
597 /// [<https://redis.io/commands/hstrlen/>](https://redis.io/commands/hstrlen/)
598 #[must_use]
599 fn hstrlen(self, key: impl Args, field: impl Args) -> PreparedCommand<'a, Self, usize> {
600 prepare_command(self, cmd("HSTRLEN").arg(key).arg(field))
601 }
602
603 /// Returns the remaining TTL (time to live) of a hash key's field(s) that have a set expiration.
604 /// This introspection capability allows you to check how many seconds
605 /// a given hash field will continue to be part of the hash key.
606 ///
607 /// # Arguments
608 /// * `key` - The hash key
609 /// * `fields` - The fields to get the TTL from.
610 ///
611 /// # Return
612 /// The TTL in seconds.
613 /// - The command returns -2 if no such field exists in the provided hash key, or the provided key does not exist.
614 /// - The command returns -1 if the field exists but has no associated expiration set.
615 ///
616 /// # See Also
617 /// [<https://redis.io/commands/httl/>](https://redis.io/commands/httl/)
618 #[must_use]
619 fn httl<R: Response>(self, key: impl Args, fields: impl Args) -> PreparedCommand<'a, Self, R> {
620 prepare_command(
621 self,
622 cmd("HTTL")
623 .arg(key)
624 .arg("FIELDS")
625 .arg(fields.num_args())
626 .arg(fields),
627 )
628 }
629
630 /// list of values in the hash, or an empty list when key does not exist.
631 ///
632 /// # Return
633 /// The list of values in the hash, or an empty list when key does not exist.
634 ///
635 /// # See Also
636 /// [<https://redis.io/commands/hvals/>](https://redis.io/commands/hvals/)
637 #[must_use]
638 fn hvals<R: Response>(self, key: impl Args) -> PreparedCommand<'a, Self, R> {
639 prepare_command(self, cmd("HVALS").arg(key))
640 }
641}
642
643/// Options for the [`hscan`](HashCommands::hscan) command
644#[derive(Default)]
645pub struct HScanOptions {
646 command_args: CommandArgs,
647}
648
649impl HScanOptions {
650 #[must_use]
651 pub fn match_pattern<P: Args>(mut self, match_pattern: P) -> Self {
652 Self {
653 command_args: self.command_args.arg("MATCH").arg(match_pattern).build(),
654 }
655 }
656
657 #[must_use]
658 pub fn count(mut self, count: usize) -> Self {
659 Self {
660 command_args: self.command_args.arg("COUNT").arg(count).build(),
661 }
662 }
663}
664
665impl Args for HScanOptions {
666 fn write_args(&self, args: &mut CommandArgs) {
667 args.arg(&self.command_args);
668 }
669}
670
671/// Result for the [`hscan`](HashCommands::hscan) command.
672#[derive(Debug, Deserialize)]
673pub struct HScanResult<F: Response + DeserializeOwned, V: Response + DeserializeOwned> {
674 pub cursor: u64,
675 #[serde(deserialize_with = "deserialize_vec_of_pairs")]
676 pub elements: Vec<(F, V)>,
677}
678
679/// Condition option for the [`hsetex`](HashCommands::hsetex) command
680#[derive(Default)]
681pub enum HSetExCondition {
682 /// No condition
683 #[default]
684 None,
685 /// Only set the fields if none of them already exist.
686 FNX,
687 /// Only set the fields if all of them already exist.
688 FXX,
689}
690
691impl Args for HSetExCondition {
692 fn write_args(&self, args: &mut CommandArgs) {
693 match self {
694 HSetExCondition::None => {}
695 HSetExCondition::FNX => {
696 args.arg("FNX");
697 }
698 HSetExCondition::FXX => {
699 args.arg("FXX");
700 }
701 }
702 }
703}