redis_driver/commands/list_commands.rs
1use crate::{
2 prepare_command,
3 resp::{
4 cmd, CommandArg, CommandArgs, FromSingleValueArray, FromValue, IntoArgs,
5 SingleArgOrCollection,
6 },
7 PreparedCommand,
8};
9
10/// A group of Redis commands related to [`Lists`](https://redis.io/docs/data-types/lists/)
11///
12/// # See Also
13/// [Redis List Commands](https://redis.io/commands/?group=list)
14pub trait ListCommands {
15 /// Returns the element at index index in the list stored at key.
16 ///
17 /// # Return
18 /// The requested element, or nil when index is out of range.
19 ///
20 /// # See Also
21 /// [<https://redis.io/commands/lindex/>](https://redis.io/commands/lindex/)
22 #[must_use]
23 fn lindex<K, E>(&mut self, key: K, index: isize) -> PreparedCommand<Self, E>
24 where
25 Self: Sized,
26 K: Into<CommandArg>,
27 E: FromValue,
28 {
29 prepare_command(self, cmd("LINDEX").arg(key).arg(index))
30 }
31
32 /// Inserts element in the list stored at key either before or after the reference value pivot.
33 ///
34 /// # Return
35 /// The length of the list after the insert operation, or -1 when the value pivot was not found.
36 ///
37 /// # See Also
38 /// [<https://redis.io/commands/linsert/>](https://redis.io/commands/linsert/)
39 #[must_use]
40 fn linsert<K, E>(
41 &mut self,
42 key: K,
43 where_: LInsertWhere,
44 pivot: E,
45 element: E,
46 ) -> PreparedCommand<Self, usize>
47 where
48 Self: Sized,
49 K: Into<CommandArg>,
50 E: Into<CommandArg>,
51 {
52 prepare_command(
53 self,
54 cmd("LINSERT").arg(key).arg(where_).arg(pivot).arg(element),
55 )
56 }
57
58 /// Inserts element in the list stored at key either before or after the reference value pivot.
59 ///
60 /// # Return
61 /// The length of the list at key.
62 ///
63 /// # See Also
64 /// [<https://redis.io/commands/llen/>](https://redis.io/commands/llen/)
65 #[must_use]
66 fn llen<K>(&mut self, key: K) -> PreparedCommand<Self, usize>
67 where
68 Self: Sized,
69 K: Into<CommandArg>,
70 {
71 prepare_command(self, cmd("LLEN").arg(key))
72 }
73
74 /// Atomically returns and removes the first/last element (head/tail depending on the wherefrom argument)
75 /// of the list stored at source, and pushes the element at the first/last element
76 /// (head/tail depending on the whereto argument) of the list stored at destination.
77 ///
78 /// # Return
79 /// The element being popped and pushed.
80 ///
81 /// # See Also
82 /// [<https://redis.io/commands/lmove/>](https://redis.io/commands/lmove/)
83 #[must_use]
84 fn lmove<S, D, E>(
85 &mut self,
86 source: S,
87 destination: D,
88 where_from: LMoveWhere,
89 where_to: LMoveWhere,
90 ) -> PreparedCommand<Self, E>
91 where
92 Self: Sized,
93 S: Into<CommandArg>,
94 D: Into<CommandArg>,
95 E: FromValue,
96 {
97 prepare_command(
98 self,
99 cmd("LMOVE")
100 .arg(source)
101 .arg(destination)
102 .arg(where_from)
103 .arg(where_to),
104 )
105 }
106
107 /// Pops one or more elements from the first non-empty list key from the list of provided key names.
108 ///
109 /// # Return
110 /// Tuple composed by the name of the key from which elements were popped and the list of popped element
111 ///
112 /// # See Also
113 /// [<https://redis.io/commands/lmpop/>](https://redis.io/commands/lmpop/)
114 #[must_use]
115 fn lmpop<K, E, C>(
116 &mut self,
117 keys: C,
118 where_: LMoveWhere,
119 count: usize,
120 ) -> PreparedCommand<Self, (String, Vec<E>)>
121 where
122 Self: Sized,
123 K: Into<CommandArg>,
124 E: FromValue,
125 C: SingleArgOrCollection<K>,
126 {
127 prepare_command(
128 self,
129 cmd("LMPOP")
130 .arg(keys.num_args())
131 .arg(keys)
132 .arg(where_)
133 .arg("COUNT")
134 .arg(count),
135 )
136 }
137
138 /// Removes and returns the first elements of the list stored at key.
139 ///
140 /// # Return
141 /// The list of popped elements, or empty collection when key does not exist.
142 ///
143 /// # See Also
144 /// [<https://redis.io/commands/lpop/>](https://redis.io/commands/lpop/)
145 #[must_use]
146 fn lpop<K, E, A>(&mut self, key: K, count: usize) -> PreparedCommand<Self, A>
147 where
148 Self: Sized,
149 K: Into<CommandArg>,
150 E: FromValue,
151 A: FromSingleValueArray<E>,
152 {
153 prepare_command(self, cmd("LPOP").arg(key).arg(count))
154 }
155
156 /// Returns the index of matching elements inside a Redis list.
157 ///
158 /// # Return
159 /// The integer representing the matching element, or nil if there is no match.
160 ///
161 /// # See Also
162 /// [<https://redis.io/commands/lpos/>](https://redis.io/commands/lpos/)
163 #[must_use]
164 fn lpos<K, E>(
165 &mut self,
166 key: K,
167 element: E,
168 rank: Option<usize>,
169 max_len: Option<usize>,
170 ) -> PreparedCommand<Self, Option<usize>>
171 where
172 Self: Sized,
173 K: Into<CommandArg>,
174 E: Into<CommandArg>,
175 {
176 prepare_command(
177 self,
178 cmd("LPOS")
179 .arg(key)
180 .arg(element)
181 .arg(rank.map(|r| ("RANK", r)))
182 .arg(max_len.map(|l| ("MAXLEN", l))),
183 )
184 }
185
186 /// Returns the index of matching elements inside a Redis list.
187 ///
188 /// # Return
189 /// An array of integers representing the matching elements.
190 /// (empty if there are no matches).
191 ///
192 /// # See Also
193 /// [<https://redis.io/commands/lpos/>](https://redis.io/commands/lpos/)
194 #[must_use]
195 fn lpos_with_count<K, E, A>(
196 &mut self,
197 key: K,
198 element: E,
199 num_matches: usize,
200 rank: Option<usize>,
201 max_len: Option<usize>,
202 ) -> PreparedCommand<Self, A>
203 where
204 Self: Sized,
205 K: Into<CommandArg>,
206 E: Into<CommandArg>,
207 A: FromSingleValueArray<usize>,
208 {
209 prepare_command(
210 self,
211 cmd("LPOS")
212 .arg(key)
213 .arg(element)
214 .arg(rank.map(|r| ("RANK", r)))
215 .arg("COUNT")
216 .arg(num_matches)
217 .arg(max_len.map(|l| ("MAXLEN", l))),
218 )
219 }
220
221 /// Insert all the specified values at the head of the list stored at key
222 ///
223 /// # Return
224 /// The length of the list after the push operations.
225 ///
226 /// # See Also
227 /// [<https://redis.io/commands/lpush/>](https://redis.io/commands/lpush/)
228 #[must_use]
229 fn lpush<K, E, C>(&mut self, key: K, elements: C) -> PreparedCommand<Self, usize>
230 where
231 Self: Sized,
232 K: Into<CommandArg>,
233 E: Into<CommandArg>,
234 C: SingleArgOrCollection<E>,
235 {
236 prepare_command(self, cmd("LPUSH").arg(key).arg(elements))
237 }
238
239 /// Inserts specified values at the head of the list stored at key,
240 /// only if key already exists and holds a list.
241 ///
242 /// # Return
243 /// The length of the list after the push operation.
244 ///
245 /// # See Also
246 /// [<https://redis.io/commands/lpushx/>](https://redis.io/commands/lpushx/)
247 #[must_use]
248 fn lpushx<K, E, C>(&mut self, key: K, elements: C) -> PreparedCommand<Self, usize>
249 where
250 Self: Sized,
251 K: Into<CommandArg>,
252 E: Into<CommandArg>,
253 C: SingleArgOrCollection<E>,
254 {
255 prepare_command(self, cmd("LPUSHX").arg(key).arg(elements))
256 }
257
258 /// Returns the specified elements of the list stored at key.
259 ///
260 /// # Return
261 /// The list of elements in the specified range.
262 ///
263 /// # See Also
264 /// [<https://redis.io/commands/lrange/>](https://redis.io/commands/lrange/)
265 #[must_use]
266 fn lrange<K, E, A>(&mut self, key: K, start: isize, stop: isize) -> PreparedCommand<Self, A>
267 where
268 Self: Sized,
269 K: Into<CommandArg>,
270 E: FromValue,
271 A: FromSingleValueArray<E>,
272 {
273 prepare_command(self, cmd("LRANGE").arg(key).arg(start).arg(stop))
274 }
275
276 /// Removes the first count occurrences of elements equal to element from the list stored at key.
277 ///
278 /// # Return
279 /// The number of removed elements.
280 ///
281 /// # See Also
282 /// [<https://redis.io/commands/lrem/>](https://redis.io/commands/lrem/)
283 #[must_use]
284 fn lrem<K, E>(&mut self, key: K, count: isize, element: E) -> PreparedCommand<Self, usize>
285 where
286 Self: Sized,
287 K: Into<CommandArg>,
288 E: Into<CommandArg>,
289 {
290 prepare_command(self, cmd("LREM").arg(key).arg(count).arg(element))
291 }
292
293 /// Sets the list element at index to element.
294 ///
295 /// # See Also
296 /// [<https://redis.io/commands/lset/>](https://redis.io/commands/lset/)
297 #[must_use]
298 fn lset<K, E>(&mut self, key: K, index: isize, element: E) -> PreparedCommand<Self, ()>
299 where
300 Self: Sized,
301 K: Into<CommandArg>,
302 E: Into<CommandArg>,
303 {
304 prepare_command(self, cmd("LSET").arg(key).arg(index).arg(element))
305 }
306
307 /// Trim an existing list so that it will contain only the specified range of elements specified.
308 ///
309 /// # See Also
310 /// [<https://redis.io/commands/ltrim/>](https://redis.io/commands/ltrim/)
311 #[must_use]
312 fn ltrim<K>(&mut self, key: K, start: isize, stop: isize) -> PreparedCommand<Self, ()>
313 where
314 Self: Sized,
315 K: Into<CommandArg>,
316 {
317 prepare_command(self, cmd("LTRIM").arg(key).arg(start).arg(stop))
318 }
319
320 /// Removes and returns the first elements of the list stored at key.
321 ///
322 /// # Return
323 /// The list of popped elements, or empty collection when key does not exist.
324 ///
325 /// # See Also
326 /// [<https://redis.io/commands/rpop/>](https://redis.io/commands/rpop/)
327 #[must_use]
328 fn rpop<K, E, C>(&mut self, key: K, count: usize) -> PreparedCommand<Self, C>
329 where
330 Self: Sized,
331 K: Into<CommandArg>,
332 E: FromValue,
333 C: FromSingleValueArray<E>,
334 {
335 prepare_command(self, cmd("RPOP").arg(key).arg(count))
336 }
337
338 /// Insert all the specified values at the tail of the list stored at key
339 ///
340 /// # Return
341 /// The length of the list after the push operations.
342 ///
343 /// # See Also
344 /// [<https://redis.io/commands/rpush/>](https://redis.io/commands/rpush/)
345 #[must_use]
346 fn rpush<K, E, C>(&mut self, key: K, elements: C) -> PreparedCommand<Self, usize>
347 where
348 Self: Sized,
349 K: Into<CommandArg>,
350 E: Into<CommandArg>,
351 C: SingleArgOrCollection<E>,
352 {
353 prepare_command(self, cmd("RPUSH").arg(key).arg(elements))
354 }
355
356 /// Inserts specified values at the tail of the list stored at key,
357 /// only if key already exists and holds a list.
358 ///
359 /// # Return
360 /// The length of the list after the push operations.
361 ///
362 /// # See Also
363 /// [<https://redis.io/commands/rpushx/>](https://redis.io/commands/rpushx/)
364 #[must_use]
365 fn rpushx<K, E, C>(&mut self, key: K, elements: C) -> PreparedCommand<Self, usize>
366 where
367 Self: Sized,
368 K: Into<CommandArg>,
369 E: Into<CommandArg>,
370 C: SingleArgOrCollection<E>,
371 {
372 prepare_command(self, cmd("RPUSHX").arg(key).arg(elements))
373 }
374}
375
376pub enum LInsertWhere {
377 Before,
378 After,
379}
380
381impl IntoArgs for LInsertWhere {
382 fn into_args(self, args: CommandArgs) -> CommandArgs {
383 args.arg(match self {
384 LInsertWhere::Before => CommandArg::Str("BEFORE"),
385 LInsertWhere::After => CommandArg::Str("AFTER"),
386 })
387 }
388}
389
390pub enum LMoveWhere {
391 Left,
392 Right,
393}
394
395impl IntoArgs for LMoveWhere {
396 fn into_args(self, args: CommandArgs) -> CommandArgs {
397 args.arg(match self {
398 LMoveWhere::Left => CommandArg::Str("LEFT"),
399 LMoveWhere::Right => CommandArg::Str("RIGHT"),
400 })
401 }
402}