redis_driver/commands/
hash_commands.rs

1use crate::{
2    prepare_command,
3    resp::{
4        cmd, CommandArg, CommandArgs, FromKeyValueValueArray, FromSingleValueArray, FromValue,
5        IntoArgs, KeyValueArgOrCollection, SingleArgOrCollection,
6    },
7    PreparedCommand,
8};
9
10/// A group of Redis commands related to [`Hashes`](https://redis.io/docs/data-types/hashes/)
11///
12/// # See Also
13/// [Redis Hash Commands](https://redis.io/commands/?group=hash)
14pub trait HashCommands {
15    /// Removes the specified fields from the hash stored at key.
16    ///
17    /// # Return
18    /// the number of fields that were removed from the hash, not including specified but non existing fields.
19    ///
20    /// # See Also
21    /// [<https://redis.io/commands/hdel/>](https://redis.io/commands/hdel/)
22    #[must_use]
23    fn hdel<K, F, C>(&mut self, key: K, fields: C) -> PreparedCommand<Self, usize>
24    where
25        Self: Sized,
26        K: Into<CommandArg>,
27        F: Into<CommandArg>,
28        C: SingleArgOrCollection<F>,
29    {
30        prepare_command(self, cmd("HDEL").arg(key).arg(fields))
31    }
32
33    /// Returns if field is an existing field in the hash stored at key.
34    ///
35    /// # Return
36    /// * `true` - if the hash contains field.
37    /// * `false` - if the hash does not contain field, or key does not exist.
38    ///
39    /// # See Also
40    /// [<https://redis.io/commands/hexists/>](https://redis.io/commands/hexists/)
41    #[must_use]
42    fn hexists<K, F>(&mut self, key: K, field: F) -> PreparedCommand<Self, bool>
43    where
44        Self: Sized,
45        K: Into<CommandArg>,
46        F: Into<CommandArg>,
47    {
48        prepare_command(self, cmd("HEXISTS").arg(key).arg(field))
49    }
50
51    /// Returns the value associated with field in the hash stored at key.
52    ///
53    /// # Return
54    /// The value associated with field, or nil when field is not present in the hash or key does not exist.
55    ///
56    /// # See Also
57    /// [<https://redis.io/commands/hget/>](https://redis.io/commands/hget/)
58    #[must_use]
59    fn hget<K, F, V>(&mut self, key: K, field: F) -> PreparedCommand<Self, V>
60    where
61        Self: Sized,
62        K: Into<CommandArg>,
63        F: Into<CommandArg>,
64        V: FromValue,
65    {
66        prepare_command(self, cmd("HGET").arg(key).arg(field))
67    }
68
69    /// Returns all fields and values of the hash stored at key.
70    ///
71    /// # Return
72    /// The list of fields and their values stored in the hash, or an empty list when key does not exist.
73    ///
74    /// # See Also
75    /// [<https://redis.io/commands/hgetall/>](https://redis.io/commands/hgetall/)
76    #[must_use]
77    fn hgetall<K, F, V, A>(&mut self, key: K) -> PreparedCommand<Self, A>
78    where
79        Self: Sized,
80        K: Into<CommandArg>,
81        F: FromValue,
82        V: FromValue,
83        A: FromKeyValueValueArray<F, V>,
84    {
85        prepare_command(self, cmd("HGETALL").arg(key))
86    }
87
88    /// Increments the number stored at field in the hash stored at key by increment.
89    ///
90    /// # Return
91    /// The value at field after the increment operation.
92    ///
93    /// # See Also
94    /// [<https://redis.io/commands/hincrby/>](https://redis.io/commands/hincrby/)
95    #[must_use]
96    fn hincrby<K, F>(&mut self, key: K, field: F, increment: i64) -> PreparedCommand<Self, i64>
97    where
98        Self: Sized,
99        K: Into<CommandArg>,
100        F: Into<CommandArg>,
101    {
102        prepare_command(self, cmd("HINCRBY").arg(key).arg(field).arg(increment))
103    }
104
105    /// Increment the specified field of a hash stored at key,
106    /// and representing a floating point number, by the specified increment.
107    ///
108    /// # Return
109    /// The value at field after the increment operation.
110    ///
111    /// # See Also
112    /// [<https://redis.io/commands/hincrbyfloat/>](https://redis.io/commands/hincrbyfloat/)
113    #[must_use]
114    fn hincrbyfloat<K, F>(&mut self, key: K, field: F, increment: f64) -> PreparedCommand<Self, f64>
115    where
116        Self: Sized,
117        K: Into<CommandArg>,
118        F: Into<CommandArg>,
119    {
120        prepare_command(self, cmd("HINCRBYFLOAT").arg(key).arg(field).arg(increment))
121    }
122
123    /// Returns all field names in the hash stored at key.
124    ///
125    /// # Return
126    /// The list of fields in the hash, or an empty list when key does not exist.
127    ///
128    /// # See Also
129    /// [<https://redis.io/commands/hkeys/>](https://redis.io/commands/hkeys/)
130    #[must_use]
131    fn hkeys<K, F, A>(&mut self, key: K) -> PreparedCommand<Self, A>
132    where
133        Self: Sized,
134        K: Into<CommandArg>,
135        F: FromValue,
136        A: FromSingleValueArray<F>,
137    {
138        prepare_command(self, cmd("HKEYS").arg(key))
139    }
140
141    /// Returns the number of fields contained in the hash stored at key.
142    ///
143    /// # Return
144    /// The number of fields in the hash, or 0 when key does not exist.
145    ///
146    /// # See Also
147    /// [<https://redis.io/commands/hlen/>](https://redis.io/commands/hlen/)
148    #[must_use]
149    fn hlen<K>(&mut self, key: K) -> PreparedCommand<Self, usize>
150    where
151        Self: Sized,
152        K: Into<CommandArg>,
153    {
154        prepare_command(self, cmd("HLEN").arg(key))
155    }
156
157    /// Returns the values associated with the specified fields in the hash stored at key.
158    ///
159    /// # Return
160    /// The list of values associated with the given fields, in the same order as they are requested.
161    ///
162    /// # See Also
163    /// [<https://redis.io/commands/hmget/>](https://redis.io/commands/hmget/)
164    #[must_use]
165    fn hmget<K, F, V, C, A>(&mut self, key: K, fields: C) -> PreparedCommand<Self, A>
166    where
167        Self: Sized,
168        K: Into<CommandArg>,
169        F: Into<CommandArg>,
170        C: SingleArgOrCollection<F>,
171        V: FromValue,
172        A: FromSingleValueArray<V>,
173    {
174        prepare_command(self, cmd("HMGET").arg(key).arg(fields))
175    }
176
177    /// return random fields from the hash value stored at key.
178    ///
179    /// # Return
180    /// * When called with just the key argument, return a random field from the hash value stored at key.
181    ///
182    /// # See Also
183    /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
184    #[must_use]
185    fn hrandfield<K, F>(&mut self, key: K) -> PreparedCommand<Self, F>
186    where
187        Self: Sized,
188        K: Into<CommandArg>,
189        F: FromValue,
190    {
191        prepare_command(self, cmd("HRANDFIELD").arg(key))
192    }
193
194    /// return random fields from the hash value stored at key.
195    ///
196    /// # Return
197    /// * If the provided count argument is positive, return an array of distinct fields.
198    /// The array's length is either count or the hash's number of fields (HLEN), whichever is lower.
199    /// * If called with a negative count, the behavior changes and the command is allowed to return the same field multiple times.
200    /// In this case, the number of returned fields is the absolute value of the specified count.
201    ///
202    /// # See Also
203    /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
204    #[must_use]
205    fn hrandfields<K, F, A>(&mut self, key: K, count: isize) -> PreparedCommand<Self, A>
206    where
207        Self: Sized,
208        K: Into<CommandArg>,
209        F: FromValue,
210        A: FromSingleValueArray<F>,
211    {
212        prepare_command(self, cmd("HRANDFIELD").arg(key).arg(count))
213    }
214
215    /// return random fields from the hash value stored at key.
216    ///
217    /// # Return
218    /// * If the provided count argument is positive, return an array of distinct fields.
219    /// The array's length is either count or the hash's number of fields (HLEN), whichever is lower.
220    /// * If called with a negative count, the behavior changes and the command is allowed to return the same field multiple times.
221    /// In this case, the number of returned fields is the absolute value of the specified count.
222    /// The optional WITHVALUES modifier changes the reply so it includes the respective values of the randomly selected hash fields.
223    ///
224    /// # See Also
225    /// [<https://redis.io/commands/hrandfield/>](https://redis.io/commands/hrandfield/)
226    #[must_use]
227    fn hrandfields_with_values<K, F, V, A>(
228        &mut self,
229        key: K,
230        count: isize,
231    ) -> PreparedCommand<Self, A>
232    where
233        Self: Sized,
234        K: Into<CommandArg>,
235        F: FromValue,
236        V: FromValue,
237        A: FromKeyValueValueArray<F, V>,
238    {
239        prepare_command(
240            self,
241            cmd("HRANDFIELD").arg(key).arg(count).arg("WITHVALUES"),
242        )
243    }
244
245    /// Iterates fields of Hash types and their associated values.
246    ///
247    /// # Return
248    /// array of elements contain two elements, a field and a value,
249    /// for every returned element of the Hash.
250    ///
251    /// # See Also
252    /// [<https://redis.io/commands/hlen/>](https://redis.io/commands/hscan/)
253    #[must_use]
254    fn hscan<K, F, V>(
255        &mut self,
256        key: K,
257        cursor: u64,
258        options: HScanOptions,
259    ) -> PreparedCommand<Self, (u64, Vec<(F, V)>)>
260    where
261        Self: Sized,
262        K: Into<CommandArg>,
263        F: FromValue,
264        V: FromValue,
265    {
266        prepare_command(self, cmd("HSCAN").arg(key).arg(cursor).arg(options))
267    }
268
269    /// Sets field in the hash stored at key to value.
270    ///
271    /// # Return
272    /// The number of fields that were added.
273    ///
274    /// # See Also
275    /// [<https://redis.io/commands/hset/>](https://redis.io/commands/hset/)
276    #[must_use]
277    fn hset<K, F, V, I>(&mut self, key: K, items: I) -> PreparedCommand<Self, usize>
278    where
279        Self: Sized,
280        K: Into<CommandArg>,
281        F: Into<CommandArg>,
282        V: Into<CommandArg>,
283        I: KeyValueArgOrCollection<F, V>,
284    {
285        prepare_command(self, cmd("HSET").arg(key).arg(items))
286    }
287
288    /// Sets field in the hash stored at key to value, only if field does not yet exist.
289    ///
290    /// # Return
291    /// * `true` - if field is a new field in the hash and value was set.
292    /// * `false` - if field already exists in the hash and no operation was performed.
293    ///
294    /// # See Also
295    /// [<https://redis.io/commands/hsetnx/>](https://redis.io/commands/hsetnx/)
296    #[must_use]
297    fn hsetnx<K, F, V>(&mut self, key: K, field: F, value: V) -> PreparedCommand<Self, bool>
298    where
299        Self: Sized,
300        K: Into<CommandArg>,
301        F: Into<CommandArg>,
302        V: Into<CommandArg>,
303    {
304        prepare_command(self, cmd("HSETNX").arg(key).arg(field).arg(value))
305    }
306
307    /// Returns the string length of the value associated with field in the hash stored at key.
308    ///
309    /// # Return
310    /// the string length of the value associated with field,
311    /// or zero when field is not present in the hash or key does not exist at all.
312    ///
313    /// # See Also
314    /// [<https://redis.io/commands/hstrlen/>](https://redis.io/commands/hstrlen/)
315    #[must_use]
316    fn hstrlen<K, F>(&mut self, key: K, field: F) -> PreparedCommand<Self, usize>
317    where
318        Self: Sized,
319        K: Into<CommandArg>,
320        F: Into<CommandArg>,
321    {
322        prepare_command(self, cmd("HSTRLEN").arg(key).arg(field))
323    }
324
325    /// list of values in the hash, or an empty list when key does not exist.
326    ///
327    /// # Return
328    /// The list of values in the hash, or an empty list when key does not exist.
329    ///
330    /// # See Also
331    /// [<https://redis.io/commands/hvals/>](https://redis.io/commands/hvals/)
332    #[must_use]
333    fn hvals<K, V, A>(&mut self, key: K) -> PreparedCommand<Self, A>
334    where
335        Self: Sized,
336        K: Into<CommandArg>,
337        V: FromValue,
338        A: FromSingleValueArray<V>,
339    {
340        prepare_command(self, cmd("HVALS").arg(key))
341    }
342}
343
344/// Options for the [`hscan`](crate::HashCommands::hscan) command
345#[derive(Default)]
346pub struct HScanOptions {
347    command_args: CommandArgs,
348}
349
350impl HScanOptions {
351    #[must_use]
352    pub fn match_pattern<P: Into<CommandArg>>(self, match_pattern: P) -> Self {
353        Self {
354            command_args: self.command_args.arg("MATCH").arg(match_pattern),
355        }
356    }
357
358    #[must_use]
359    pub fn count(self, count: usize) -> Self {
360        Self {
361            command_args: self.command_args.arg("COUNT").arg(count),
362        }
363    }
364}
365
366impl IntoArgs for HScanOptions {
367    fn into_args(self, args: CommandArgs) -> CommandArgs {
368        args.arg(self.command_args)
369    }
370}