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}