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}