redisclient/
client.rs

1use std::collections::HashSet;
2use std::hash::Hash;
3
4use crate::config::RedisConfig;
5use crate::connection::Reply;
6use crate::error::{ErrorKind, RedisError};
7use crate::pool::ConnectionPool;
8use crate::protocol::{RedisDeserializationProtocol, RedisSerializationProtocol};
9use crate::{DataType, RedisResult};
10
11struct Command {
12    cmd: String,
13    args: Vec<u8>,
14    count: usize,
15}
16
17impl Command {
18    fn new<S: ToString>(cmd: S) -> Command {
19        let cmd = cmd.to_string();
20        let args = Vec::new();
21        Command { cmd, args, count: 1 }
22    }
23
24    fn arg<T: RedisSerializationProtocol>(&mut self, arg: T) -> &mut Self {
25        self.args.extend(arg.serialization());
26        self.count += 1;
27        self
28    }
29
30    fn into_vec(self) -> Vec<u8> {
31        let Command { cmd, args, count } = self;
32
33        let mut buf = Vec::new();
34        buf.extend(Vec::from(format!("*{}\r\n", count)));
35        buf.extend(cmd.serialization());
36        buf.extend(args);
37        buf
38    }
39}
40
41macro_rules! command {
42    ($name: expr; args => $($args: expr),*) => {
43        {
44            let mut cmd = Command::new($name);
45            $(cmd.arg($args);)*
46            cmd
47        }
48    };
49}
50
51// TODO: remove
52pub enum ListBeforeOrAfter {
53    Before,
54    After,
55}
56
57pub struct RedisClient {
58    pool: ConnectionPool,
59}
60
61impl RedisClient {
62    pub fn new() -> RedisResult<RedisClient> {
63        let config = RedisConfig::default();
64
65        Self::with_config(config)
66    }
67
68    pub fn with_config(config: RedisConfig) -> RedisResult<RedisClient> {
69        let RedisConfig {
70            address,
71            database,
72            username,
73            password,
74            pool_capacity,
75        } = config;
76
77        let mut client = RedisClient {
78            pool: ConnectionPool::new(pool_capacity, address),
79        };
80
81        if let Some(password) = password {
82            client.auth(username, password)?;
83        }
84
85        if database > 0 {
86            client.select(database)?;
87        }
88
89        Ok(client)
90    }
91
92    // TODO
93    pub fn flushall(&mut self) -> RedisResult<()> {
94        let cmd = Command::new("FLUSHALL");
95
96        let reply = self.execute(cmd)?;
97        <()>::deserialization(reply)
98    }
99
100    // Connection commands
101    /// The AUTH command authenticates the current connection
102    ///
103    /// Return value: Simple string reply
104    pub fn auth<S>(&mut self, username: Option<S>, password: S) -> RedisResult<()>
105    where
106        S: ToString,
107    {
108        let mut cmd = Command::new("AUTH");
109        if let Some(username) = username {
110            cmd.arg(username.to_string());
111        }
112        cmd.arg(password.to_string());
113        let reply = self.execute(cmd)?;
114        <()>::deserialization(reply)
115    }
116
117    /// Returns message.
118    ///
119    /// Return value: Bulk string reply
120    pub fn echo<S>(&mut self, message: S) -> RedisResult<String>
121    where
122        S: ToString,
123    {
124        let cmd = command!("ECHO"; args => message.to_string());
125        let reply = self.execute(cmd)?;
126        <String>::deserialization(reply)
127    }
128
129    /// Returns PONG if no argument is provided, otherwise return a copy of the argument as a bulk.
130    ///
131    /// Return value: Simple string reply
132    pub fn ping(&mut self) -> RedisResult<()> {
133        let cmd = Command::new("PING");
134        let reply = self.execute(cmd)?;
135        <()>::deserialization(reply)
136    }
137
138    /// Ask the server to close the connection.
139    ///
140    /// Return value: Simple string reply
141    pub fn quit(&mut self) -> RedisResult<()> {
142        let cmd = Command::new("QUIT");
143        let reply = self.execute(cmd)?;
144        <()>::deserialization(reply)
145    }
146
147    /// Select the Redis logical database having the specified zero-based numeric index.
148    ///
149    /// Return value: Simple string reply
150    pub fn select(&mut self, index: u8) -> RedisResult<()> {
151        let cmd = command!("SELECT"; args => index);
152        let reply = self.execute(cmd)?;
153        <()>::deserialization(reply)
154    }
155
156    // Hashes commands
157    /// Removes the specified fields from the hash stored at key.
158    ///
159    /// Return value: Integer reply
160    pub fn hdel<K>(&mut self, key: K, fields: Vec<K>) -> RedisResult<usize>
161    where
162        K: RedisSerializationProtocol,
163    {
164        let mut cmd = command!("HDEL"; args => key);
165        for field in fields {
166            cmd.arg(field);
167        }
168        let reply = self.execute(cmd)?;
169        <usize>::deserialization(reply)
170    }
171
172    /// Returns if field is an existing field in the hash stored at key.
173    ///
174    /// Return value: Integer reply
175    pub fn hexists<K, F>(&mut self, key: K, field: F) -> RedisResult<bool>
176    where
177        K: RedisSerializationProtocol,
178        F: RedisSerializationProtocol,
179    {
180        let cmd = command!("HEXISTS"; args => key, field);
181
182        let reply = self.execute(cmd)?;
183        <bool>::deserialization(reply)
184    }
185
186    /// Returns the value associated with field in the hash stored at key.
187    ///
188    /// Return value: Bulk string reply
189    pub fn hget<K, F, V>(&mut self, key: K, field: F) -> RedisResult<V>
190    where
191        K: RedisSerializationProtocol,
192        F: RedisSerializationProtocol,
193        V: RedisDeserializationProtocol,
194    {
195        let cmd = command!("HGET"; args => key, field);
196        let reply = self.execute(cmd)?;
197        <V>::deserialization(reply)
198    }
199
200    /// Returns all fields and values of the hash stored at key.
201    ///
202    /// Return value: Array reply
203    pub fn hgetall<K, M>(&mut self, key: K) -> RedisResult<M>
204    where
205        K: RedisSerializationProtocol,
206        M: RedisDeserializationProtocol,
207    {
208        let cmd = command!("HGETALL"; args => key);
209        let reply = self.execute(cmd)?;
210        <M>::deserialization(reply)
211    }
212
213    /// Increments the number stored at field in the hash stored at key by increment.
214    ///
215    /// Return value: Integer value
216    pub fn hincrby<K, F>(&mut self, key: K, field: F, increment: i64) -> RedisResult<i64>
217    where
218        K: RedisSerializationProtocol,
219        F: RedisSerializationProtocol,
220    {
221        let cmd = command!("HINCRBY"; args => key, field, increment);
222        let reply = self.execute(cmd)?;
223        <i64>::deserialization(reply)
224    }
225
226    /// Increment the specified field of a hash stored at key, and representing a floating point number, by the specified increment.
227    ///
228    /// Return value: Bulk string reply
229    pub fn hincrbyfloat<K, F>(&mut self, key: K, field: F, increment: f64) -> RedisResult<f64>
230    where
231        K: RedisSerializationProtocol,
232        F: RedisSerializationProtocol,
233    {
234        let cmd = command!("HINCRBYFLOAT"; args => key, field, increment);
235        let reply = self.execute(cmd)?;
236        <f64>::deserialization(reply)
237    }
238
239    /// Returns all field names in the hash stored at key.
240    ///
241    /// Return value: Array reply
242    pub fn hkeys<K, V>(&mut self, key: K) -> RedisResult<Vec<V>>
243    where
244        K: RedisSerializationProtocol,
245        V: RedisDeserializationProtocol,
246    {
247        let cmd = command!("HKEYS"; args => key);
248        let reply = self.execute(cmd)?;
249        <Vec<V>>::deserialization(reply)
250    }
251
252    /// Returns the number of fields contained in the hash stored at key.
253    ///
254    /// Return value: Integer reply
255    pub fn hlen<K>(&mut self, key: K) -> RedisResult<u64>
256    where
257        K: RedisSerializationProtocol,
258    {
259        let cmd = command!("HLEN"; args => key);
260        let reply = self.execute(cmd)?;
261        <u64>::deserialization(reply)
262    }
263
264    /// Returns the values associated with the specified fields in the hash stored at key.
265    ///
266    /// Return value: Array reply
267    pub fn hmget<K, F, V>(&mut self, key: K, fields: Vec<F>) -> RedisResult<Vec<V>>
268    where
269        K: RedisSerializationProtocol,
270        F: RedisSerializationProtocol,
271        V: RedisDeserializationProtocol,
272    {
273        let mut cmd = command!("HMGET"; args => key);
274        for field in fields {
275            cmd.arg(field);
276        }
277        let reply = self.execute(cmd)?;
278        <Vec<V>>::deserialization(reply)
279    }
280
281    /// Sets the specified fields to their respective values in the hash stored at key.
282    ///
283    /// Return values: Simple string reply
284    pub fn hmset<K, F, V>(&mut self, key: K, fvs: Vec<(F, V)>) -> RedisResult<()>
285    where
286        K: RedisSerializationProtocol,
287        F: RedisSerializationProtocol,
288        V: RedisSerializationProtocol,
289    {
290        let mut cmd = command!("HMSET"; args => key);
291        for (field, value) in fvs {
292            cmd.arg(field).arg(value);
293        }
294        let reply = self.execute(cmd)?;
295        <()>::deserialization(reply)
296    }
297
298    pub fn hscan(&mut self) {
299        todo!();
300    }
301
302    /// Sets field in the hash stored at key to value.
303    ///
304    /// Return value: Integer reply
305    pub fn hset<K, F, V>(&mut self, key: K, field: F, value: V) -> RedisResult<usize>
306    where
307        K: RedisSerializationProtocol,
308        F: RedisSerializationProtocol,
309        V: RedisSerializationProtocol,
310    {
311        let cmd = command!("HSET"; args => key, field, value);
312        let reply = self.execute(cmd)?;
313        <usize>::deserialization(reply)
314    }
315
316    /// Sets field in the hash stored at key to value, only if field does not yet exist.
317    ///
318    /// Return value: Integer value
319    pub fn hsetnx<K, F, V>(&mut self, key: K, field: F, value: V) -> RedisResult<usize>
320    where
321        K: RedisSerializationProtocol,
322        F: RedisSerializationProtocol,
323        V: RedisSerializationProtocol,
324    {
325        let cmd = command!("HSETNX"; args => key, field, value);
326        let reply = self.execute(cmd)?;
327        <usize>::deserialization(reply)
328    }
329
330    /// Returns the string length of the value associated with field in the hash stored at key.
331    ///
332    /// Return value: Integer reply
333    pub fn hstrlen<K, F>(&mut self, key: K, field: F) -> RedisResult<usize>
334    where
335        K: RedisSerializationProtocol,
336        F: RedisSerializationProtocol,
337    {
338        let cmd = command!("HSTRLEN"; args => key, field);
339        let reply = self.execute(cmd)?;
340        <usize>::deserialization(reply)
341    }
342
343    /// Returns all values in the hash stored at key.
344    ///
345    /// Return value: Array reply
346    pub fn hvals<K, V>(&mut self, key: K) -> RedisResult<Vec<V>>
347    where
348        K: RedisSerializationProtocol,
349        V: RedisDeserializationProtocol,
350    {
351        let cmd = command!("HVALS"; args => key);
352        let reply = self.execute(cmd)?;
353        <Vec<V>>::deserialization(reply)
354    }
355
356    // keys command
357    /// This command copies the value stored at the source key to the destination key.
358    ///
359    /// Return value: Integer reply
360    pub fn copy(&mut self) -> RedisResult<()> {
361        todo!()
362    }
363
364    /// Removes the specified keys. A key is ignored if it does not exist.
365    ///
366    /// Return value: Integer reply
367    pub fn del<K>(&mut self, keys: Vec<K>) -> RedisResult<usize>
368    where
369        K: RedisSerializationProtocol,
370    {
371        let mut cmd = Command::new("DEL");
372        for key in keys {
373            cmd.arg(key);
374        }
375
376        let reply = self.execute(cmd)?;
377        <usize>::deserialization(reply)
378    }
379
380    /// Serialize the value stored at key in a Redis-specific format and return it to the user.
381    ///
382    /// Return value: Bulk string reply
383    #[allow(unused_variables)]
384    pub fn dump<K>(&mut self, key: K) -> RedisResult<String>
385    where
386        K: RedisSerializationProtocol,
387    {
388        // let mut cmd = Command::new("DUMP");
389        // cmd.arg(key);
390        //
391        // let reply = self.execute(cmd)?;
392        // <String>::deserialization(reply)
393        todo!()
394    }
395
396    /// Returns if key exists.
397    ///
398    /// Return value: Integer reply
399    pub fn exists<K>(&mut self, keys: Vec<K>) -> RedisResult<usize>
400    where
401        K: RedisSerializationProtocol,
402    {
403        let mut cmd = Command::new("EXISTS");
404        for key in keys {
405            cmd.arg(key);
406        }
407
408        let reply = self.execute(cmd)?;
409        <usize>::deserialization(reply)
410    }
411
412    /// Set a timeout on key. After the timeout has expired, the key will automatically be deleted.
413    ///
414    /// Return value: Integer reply
415    pub fn expire<K>(&mut self, key: K, seconds: usize) -> RedisResult<bool>
416    where
417        K: RedisSerializationProtocol,
418    {
419        let cmd = command!("EXPIRE"; args => key, seconds);
420        let reply = self.execute(cmd)?;
421        <bool>::deserialization(reply)
422    }
423
424    /// EXPIREAT has the same effect and semantic as EXPIRE, but instead of specifying the number of seconds representing the TTL, it takes an absolute Unix timestamp.
425    ///
426    /// Return value: Integer reply
427    #[allow(unused_variables)]
428    pub fn expireat<K>(&mut self, key: K, timestamp: u64) -> RedisResult<bool>
429    where
430        K: RedisSerializationProtocol,
431    {
432        todo!()
433    }
434
435    /// Returns all keys matching pattern.
436    ///
437    /// Return value: Array reply
438    pub fn keys<S>(&mut self, pattern: S) -> RedisResult<Vec<String>>
439    where
440        S: ToString,
441    {
442        let cmd = command!("KEYS"; args => pattern.to_string());
443        let reply = self.execute(cmd)?;
444        <Vec<String>>::deserialization(reply)
445    }
446
447    /// Remove the existing timeout on key, turning the key from volatile to persistent.
448    ///
449    /// Return value: Integer reply
450    pub fn persist<K>(&mut self, key: K) -> RedisResult<bool>
451    where
452        K: RedisSerializationProtocol,
453    {
454        let cmd = command!("PERSIST"; args => key);
455        let reply = self.execute(cmd)?;
456        <bool>::deserialization(reply)
457    }
458
459    /// This command works exactly like EXPIRE but the time to live of the key is specified in milliseconds instead of seconds.
460    ///
461    /// Return value: Integer reply
462    pub fn pexpire<K>(&mut self, key: K, milliseconds: u64) -> RedisResult<bool>
463    where
464        K: RedisSerializationProtocol,
465    {
466        let cmd = command!("PEXPIRE"; args => key, milliseconds);
467        let reply = self.execute(cmd)?;
468        <bool>::deserialization(reply)
469    }
470
471    /// Like TTL this command returns the remaining time to live of a key that has an expire set,
472    /// with the sole difference that TTL returns the amount of remaining time in seconds while PTTL returns it in milliseconds.
473    ///
474    /// Return value: Integer reply
475    pub fn pttl<K>(&mut self, key: K) -> RedisResult<i64>
476    where
477        K: RedisSerializationProtocol,
478    {
479        let cmd = command!("PTTL"; args => key);
480        let reply = self.execute(cmd)?;
481        <i64>::deserialization(reply)
482    }
483
484    /// Return a random key from the currently selected database.
485    ///
486    /// Return value: Bulk string reply
487    pub fn randomkey(&mut self) -> RedisResult<String> {
488        let cmd = Command::new("RANDOMKEY");
489        let reply = self.execute(cmd)?;
490        <String>::deserialization(reply)
491    }
492
493    /// Renames key to newkey. It returns an error when key does not exist.
494    ///
495    /// Return value: Simple string reply
496    pub fn rename<K>(&mut self, key: K, newkey: K) -> RedisResult<()>
497    where
498        K: RedisSerializationProtocol,
499    {
500        let cmd = command!("RENAME"; args => key, newkey);
501        let reply = self.execute(cmd)?;
502        <()>::deserialization(reply)
503    }
504
505    /// Renames key to newkey if newkey does not yet exist. It returns an error when key does not exist.
506    ///
507    /// Return value: Integer reply
508    pub fn renamenx<K>(&mut self, key: K, newkey: K) -> RedisResult<bool>
509    where
510        K: RedisSerializationProtocol,
511    {
512        let cmd = command!("RENAMENX"; args => key, newkey);
513        let reply = self.execute(cmd)?;
514        <bool>::deserialization(reply)
515    }
516
517    /// Alters the last access time of a key(s). A key is ignored if it does not exist.
518    ///
519    /// Return value: Integer reply
520    pub fn touch<K>(&mut self, keys: Vec<K>) -> RedisResult<isize>
521    where
522        K: RedisSerializationProtocol,
523    {
524        let mut cmd = Command::new("TOUCH");
525        for key in keys {
526            cmd.arg(key);
527        }
528        let reply = self.execute(cmd)?;
529        <isize>::deserialization(reply)
530    }
531
532    /// Returns the remaining time to live of a key that has a timeout.
533    ///
534    /// Return value: Integer reply
535    pub fn ttl<K>(&mut self, key: K) -> RedisResult<isize>
536    where
537        K: RedisSerializationProtocol,
538    {
539        let cmd = command!("TTL"; args => key);
540        let reply = self.execute(cmd)?;
541        <isize>::deserialization(reply)
542    }
543
544    /// Returns the string representation of the type of the value stored at key.
545    ///
546    /// Return value: Simple string reply
547    pub fn type_<K>(&mut self, key: K) -> RedisResult<DataType>
548    where
549        K: RedisSerializationProtocol,
550    {
551        let cmd = command!("TYPE"; args => key);
552        let reply = self.execute(cmd)?;
553        <DataType>::deserialization(reply)
554    }
555
556    /// This command is very similar to DEL: it removes the specified keys.
557    ///
558    /// Return value: Integer reply
559    pub fn unlink<K>(&mut self, keys: Vec<K>) -> RedisResult<usize>
560    where
561        K: RedisSerializationProtocol,
562    {
563        let mut cmd = Command::new("UNLINK");
564        for key in keys {
565            cmd.arg(key);
566        }
567        let reply = self.execute(cmd)?;
568        <usize>::deserialization(reply)
569    }
570
571    /// BRPOPLPUSH is the blocking variant of RPOPLPUSH.
572    ///
573    /// Return value: Bulk string reply
574    pub fn brpoplpush<K, E>(&mut self, source: K, destination: K, timeout: usize) -> RedisResult<E>
575    where
576        K: RedisSerializationProtocol,
577        E: RedisDeserializationProtocol,
578    {
579        let cmd = command!("BRPOPLPUSH"; args => source, destination, timeout);
580        let reply = self.execute(cmd)?;
581        <E>::deserialization(reply)
582    }
583
584    // Lists commands
585    /// Returns the element at index index in the list stored at key.
586    ///
587    /// Return value: Bulk string reply
588    pub fn lindex<K, V>(&mut self, key: K, index: isize) -> RedisResult<V>
589    where
590        K: RedisSerializationProtocol,
591        V: RedisDeserializationProtocol,
592    {
593        let cmd = command!("LINDEX"; args => key, index);
594        let reply = self.execute(cmd)?;
595        <V>::deserialization(reply)
596    }
597
598    /// Inserts element in the list stored at key either before or after the reference value pivot.
599    ///
600    /// Return value: Integer reply
601    pub fn linsert<K, E>(&mut self, key: K, operator: ListBeforeOrAfter, pivot: E, element: E) -> RedisResult<usize>
602    where
603        K: RedisSerializationProtocol,
604        E: RedisSerializationProtocol,
605    {
606        let cmd = command!("LINSERT"; args => key, operator, pivot, element);
607        let reply = self.execute(cmd)?;
608        <usize>::deserialization(reply)
609    }
610
611    /// Returns the length of the list stored at key.
612    ///
613    /// Return value: Integer reply
614    pub fn llen<K>(&mut self, key: K) -> RedisResult<usize>
615    where
616        K: RedisSerializationProtocol,
617    {
618        let cmd = command!("LLEN"; args => key);
619        let reply = self.execute(cmd)?;
620        <usize>::deserialization(reply)
621    }
622
623    /// Removes and returns the first element of the list stored at key.
624    ///
625    /// Return value: Bulk string reply
626    pub fn lpop<K, E>(&mut self, key: K) -> RedisResult<E>
627    where
628        K: RedisSerializationProtocol,
629        E: RedisDeserializationProtocol,
630    {
631        let cmd = command!("LPOP"; args => key);
632        let reply = self.execute(cmd)?;
633        <E>::deserialization(reply)
634    }
635
636    /// The command returns the index of matching elements inside a Redis list.
637    pub fn lpos(&mut self) {
638        todo!()
639    }
640
641    /// Insert all the specified values at the head of the list stored at key.
642    ///
643    /// Retrun value: Integer reply
644    pub fn lpush<K, E>(&mut self, key: K, elements: Vec<E>) -> RedisResult<usize>
645    where
646        K: RedisSerializationProtocol,
647        E: RedisSerializationProtocol,
648    {
649        let mut cmd = command!("LPUSH"; args => key);
650        for element in elements {
651            cmd.arg(element);
652        }
653        let reply = self.execute(cmd)?;
654        <usize>::deserialization(reply)
655    }
656
657    /// Inserts specified values at the head of the list stored at key, only if key already exists and holds a list.
658    ///
659    /// Return value: Integer value
660    pub fn lpushx<K, E>(&mut self, key: K, elements: Vec<E>) -> RedisResult<usize>
661    where
662        K: RedisSerializationProtocol,
663        E: RedisSerializationProtocol,
664    {
665        let mut cmd = command!("LPUSHX"; args => key);
666        for element in elements {
667            cmd.arg(element);
668        }
669        let reply = self.execute(cmd)?;
670        <usize>::deserialization(reply)
671    }
672
673    /// Returns the specified elements of the list stored at key.
674    ///
675    /// Return value: Array reply
676    pub fn lrange<K, E>(&mut self, key: K, start: isize, end: isize) -> RedisResult<Vec<E>>
677    where
678        K: RedisSerializationProtocol,
679        E: RedisDeserializationProtocol,
680    {
681        let cmd = command!("LRANGE"; args => key, start, end);
682        let reply = self.execute(cmd)?;
683        <Vec<E>>::deserialization(reply)
684    }
685
686    /// Removes the first count occurrences of elements equal to element from the list stored at key.
687    ///
688    /// Return value: Integer reply
689    pub fn lrem<K, E>(&mut self, key: K, count: isize, element: E) -> RedisResult<usize>
690    where
691        K: RedisSerializationProtocol,
692        E: RedisSerializationProtocol,
693    {
694        let cmd = command!("LREM"; args => key, count, element);
695        let reply = self.execute(cmd)?;
696        <usize>::deserialization(reply)
697    }
698
699    /// Sets the list element at index to element.
700    ///
701    /// Return value: Simple string reply
702    pub fn lset<K, E>(&mut self, key: K, index: isize, element: E) -> RedisResult<()>
703    where
704        K: RedisSerializationProtocol,
705        E: RedisSerializationProtocol,
706    {
707        let cmd = command!("LSET"; args => key, index, element);
708        let reply = self.execute(cmd)?;
709        <()>::deserialization(reply)
710    }
711
712    /// Trim an existing list so that it will contain only the specified range of elements specified.
713    ///
714    /// Return value: Simple string reply
715    pub fn ltrim<K>(&mut self, key: K, start: isize, stop: isize) -> RedisResult<()>
716    where
717        K: RedisSerializationProtocol,
718    {
719        let cmd = command!("LTRIM"; args => key, start, stop);
720        let reply = self.execute(cmd)?;
721        <()>::deserialization(reply)
722    }
723
724    /// Removes and returns the last element of the list stored at key.
725    ///
726    /// Return value: Bulk string reply
727    pub fn rpop<K, E>(&mut self, key: K) -> RedisResult<E>
728    where
729        K: RedisSerializationProtocol,
730        E: RedisDeserializationProtocol,
731    {
732        let cmd = command!("RPOP"; args => key);
733        let reply = self.execute(cmd)?;
734        <E>::deserialization(reply)
735    }
736
737    /// Atomically returns and removes the last element (tail) of the list stored at source, and
738    /// pushes the element at the first element (head) of the list stored at destination.
739    ///
740    /// Return value: Bulk string reply
741    pub fn rpoplpush<K, E>(&mut self, source: K, destination: K) -> RedisResult<E>
742    where
743        K: RedisSerializationProtocol,
744        E: RedisDeserializationProtocol,
745    {
746        let cmd = command!("RPOPLPUSH"; args => source, destination);
747        let reply = self.execute(cmd)?;
748        <E>::deserialization(reply)
749    }
750
751    /// Insert all the specified values at the tail of the list stored at key.
752    ///
753    /// Return value: Integer value
754    pub fn rpush<K, E>(&mut self, key: K, elements: Vec<E>) -> RedisResult<usize>
755    where
756        K: RedisSerializationProtocol,
757        E: RedisSerializationProtocol,
758    {
759        let mut cmd = command!("RPUSH"; args => key);
760        for element in elements {
761            cmd.arg(element);
762        }
763        let reply = self.execute(cmd)?;
764        <usize>::deserialization(reply)
765    }
766
767    /// Inserts specified values at the tail of the list stored at key, only if key already exists and holds a list.
768    ///
769    /// Return value: Integer reply
770    pub fn rpushx<K, E>(&mut self, key: K, elements: Vec<E>) -> RedisResult<usize>
771    where
772        K: RedisSerializationProtocol,
773        E: RedisSerializationProtocol,
774    {
775        let mut cmd = command!("RPUSHX"; args => key);
776        for element in elements {
777            cmd.arg(element);
778        }
779        let reply = self.execute(cmd)?;
780        <usize>::deserialization(reply)
781    }
782
783    // Sets commands
784    /// Add the specified members to the set stored at key.
785    ///
786    /// Return value: Integer value
787    pub fn sadd<K, M>(&mut self, key: K, members: HashSet<M>) -> RedisResult<usize>
788    where
789        K: RedisSerializationProtocol,
790        M: RedisSerializationProtocol + Hash + Eq,
791    {
792        let mut cmd = command!("SADD"; args => key);
793        for memeber in members {
794            cmd.arg(memeber);
795        }
796        let reply = self.execute(cmd)?;
797        <usize>::deserialization(reply)
798    }
799
800    /// Returns the set cardinality (number of elements) of the set stored at key.
801    ///
802    /// Return value: Integer reply
803    pub fn scard<K>(&mut self, key: K) -> RedisResult<usize>
804    where
805        K: RedisSerializationProtocol,
806    {
807        let cmd = command!("SCARD"; args => key);
808        let reply = self.execute(cmd)?;
809        <usize>::deserialization(reply)
810    }
811
812    /// Returns the members of the set resulting from the difference between the first set and all the successive sets.
813    ///
814    /// Return value: Array reply
815    pub fn sdiff<K, M>(&mut self, keys: Vec<K>) -> RedisResult<HashSet<M>>
816    where
817        K: RedisSerializationProtocol,
818        M: RedisDeserializationProtocol + Hash + Eq,
819    {
820        let mut cmd = Command::new("SDIFF");
821        for key in keys {
822            cmd.arg(key);
823        }
824        let reply = self.execute(cmd)?;
825        <HashSet<M>>::deserialization(reply)
826    }
827
828    /// This command is equal to SDIFF, but instead of returning the resulting set, it is stored in destination.
829    ///
830    /// Return value: Integer reply
831    pub fn sdiffstore<K>(&mut self, destination: K, keys: Vec<K>) -> RedisResult<usize>
832    where
833        K: RedisSerializationProtocol + Hash + Eq,
834    {
835        let mut cmd = command!("SDIFFSTORE"; args => destination);
836        for key in keys {
837            cmd.arg(key);
838        }
839        let reply = self.execute(cmd)?;
840        <usize>::deserialization(reply)
841    }
842
843    /// Returns the members of the set resulting from the intersection of all the given sets.
844    ///
845    /// Return value: Array reply
846    pub fn sinter<K, M>(&mut self, keys: Vec<K>) -> RedisResult<HashSet<M>>
847    where
848        K: RedisSerializationProtocol,
849        M: RedisDeserializationProtocol + Hash + Eq,
850    {
851        let mut cmd = Command::new("SINTER");
852        for key in keys {
853            cmd.arg(key);
854        }
855        let reply = self.execute(cmd)?;
856        <HashSet<M>>::deserialization(reply)
857    }
858
859    /// This command is equal to SINTER, but instead of returning the resulting set, it is stored in destination.
860    ///
861    /// Return value: Integer reply
862    pub fn sinterstore<K>(&mut self, destination: K, keys: Vec<K>) -> RedisResult<usize>
863    where
864        K: RedisSerializationProtocol,
865    {
866        let mut cmd = command!("SINTERSTORE"; args => destination);
867        for key in keys {
868            cmd.arg(key);
869        }
870        let reply = self.execute(cmd)?;
871        <usize>::deserialization(reply)
872    }
873
874    /// Returns if member is a member of the set stored at key.
875    ///
876    /// Return value: Integer reply
877    pub fn sismember<K, M>(&mut self, key: K, member: M) -> RedisResult<bool>
878    where
879        K: RedisSerializationProtocol,
880        M: RedisSerializationProtocol + Hash + Eq,
881    {
882        let cmd = command!("SISMEMBER"; args => key, member);
883        let reply = self.execute(cmd)?;
884        <bool>::deserialization(reply)
885    }
886
887    /// Returns all the members of the set value stored at key.
888    ///
889    /// Return value: Array reply
890    pub fn smembers<K, M>(&mut self, key: K) -> RedisResult<HashSet<M>>
891    where
892        K: RedisSerializationProtocol,
893        M: RedisDeserializationProtocol + Hash + Eq,
894    {
895        let cmd = command!("SMEMBERS"; args => key);
896        let reply = self.execute(cmd)?;
897        <HashSet<M>>::deserialization(reply)
898    }
899
900    /// Returns whether each member is a member of the set stored at key.
901    ///
902    /// Return value: Array reply
903    pub fn smismember<K, M>(&mut self, key: K, members: HashSet<M>) -> RedisResult<Vec<bool>>
904    where
905        K: RedisSerializationProtocol,
906        M: RedisSerializationProtocol + Hash + Eq,
907    {
908        let mut cmd = command!("SMISMEMBER"; args => key);
909        for member in members {
910            cmd.arg(member);
911        }
912        let reply = self.execute(cmd)?;
913        <Vec<bool>>::deserialization(reply)
914    }
915
916    /// Move member from the set at source to the set at destination.
917    ///
918    /// Return value: Integer reply
919    pub fn smove<K, M>(&mut self, source: K, destination: K, member: M) -> RedisResult<usize>
920    where
921        K: RedisSerializationProtocol,
922        M: RedisSerializationProtocol + Hash + Eq,
923    {
924        let cmd = command!("SMOVE"; args => source, destination, member);
925        let reply = self.execute(cmd)?;
926        <usize>::deserialization(reply)
927    }
928
929    /// Removes and returns one or more random members from the set value store at key.
930    ///
931    /// Return value: Bulk string reply or Array reply
932    pub fn spop<K, M>(&mut self, key: K, count: Option<usize>) -> RedisResult<M>
933    where
934        K: RedisSerializationProtocol,
935        M: RedisDeserializationProtocol,
936    {
937        let mut cmd = command!("SPOP"; args => key);
938        if let Some(count) = count {
939            cmd.arg(count);
940        }
941        let reply = self.execute(cmd)?;
942        <M>::deserialization(reply)
943    }
944
945    /// When called with just the key argument, return a random element from the set value stored at key.
946    ///
947    /// Return value: Bulk string reply or Array reply
948    pub fn srandmember<K, M>(&mut self, key: K, count: Option<usize>) -> RedisResult<M>
949    where
950        K: RedisSerializationProtocol,
951        M: RedisDeserializationProtocol,
952    {
953        let mut cmd = command!("SPOP"; args => key);
954        if let Some(count) = count {
955            cmd.arg(count);
956        }
957        let reply = self.execute(cmd)?;
958        <M>::deserialization(reply)
959    }
960
961    /// Remove the specified members from the set stored at key.
962    ///
963    /// Return value: Integer reply
964    pub fn srem<K, M>(&mut self, key: K, members: HashSet<M>) -> RedisResult<usize>
965    where
966        K: RedisSerializationProtocol,
967        M: RedisSerializationProtocol + Hash + Eq,
968    {
969        let mut cmd = command!("SREM"; args => key);
970        for member in members {
971            cmd.arg(member);
972        }
973        let reply = self.execute(cmd)?;
974        <usize>::deserialization(reply)
975    }
976
977    /// Like Scan command
978    pub fn sscan() {
979        todo!()
980    }
981
982    /// Returns the members of the set resulting from the union of all the given sets.
983    ///
984    /// Return value: Array reply
985    pub fn sunion<K, M>(&mut self, keys: Vec<K>) -> RedisResult<HashSet<M>>
986    where
987        K: RedisSerializationProtocol,
988        M: RedisDeserializationProtocol + Hash + Eq,
989    {
990        let mut cmd = Command::new("SUNION");
991        for key in keys {
992            cmd.arg(key);
993        }
994        let reply = self.execute(cmd)?;
995        <HashSet<M>>::deserialization(reply)
996    }
997
998    /// This command is equal to SUNION, but instead of returning the resulting set, it is stored in destination.
999    ///
1000    /// Return value: Integer reply
1001    pub fn sunionstore<K>(&mut self, destination: K, keys: Vec<K>) -> RedisResult<usize>
1002    where
1003        K: RedisSerializationProtocol,
1004    {
1005        let mut cmd = command!("SUNIONSTORE"; args => destination);
1006        for key in keys {
1007            cmd.arg(key);
1008        }
1009        let reply = self.execute(cmd)?;
1010        <usize>::deserialization(reply)
1011    }
1012
1013    // Sorted Sets commands
1014
1015    // Strings commands
1016    pub fn append<K, V>(&mut self, key: K, value: V) -> RedisResult<u64>
1017    where
1018        K: RedisSerializationProtocol,
1019        V: RedisSerializationProtocol,
1020    {
1021        let cmd = command!("APPEND"; args => key, value);
1022        let reply = self.execute(cmd)?;
1023        <u64>::deserialization(reply)
1024    }
1025
1026    /// Count the number of set bits (population counting) in a string.
1027    pub fn bitcount<K>(&mut self, key: K, start: Option<i64>, end: Option<i64>) -> RedisResult<u64>
1028    where
1029        K: RedisSerializationProtocol,
1030    {
1031        let mut cmd = command!("BITCOUNT"; args => key);
1032        if let Some(start) = start {
1033            cmd.arg(start);
1034        }
1035        if let Some(end) = end {
1036            cmd.arg(end);
1037        }
1038
1039        let reply = self.execute(cmd)?;
1040        <u64>::deserialization(reply)
1041    }
1042
1043    /// Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key.
1044    pub fn bitop<K1, K2>(&mut self, operation: &str, destkey: K1, keys: Vec<K2>) -> RedisResult<usize>
1045    where
1046        K1: RedisSerializationProtocol,
1047        K2: RedisSerializationProtocol,
1048    {
1049        let mut cmd = command!("BITOP"; args => operation, destkey);
1050        for key in keys {
1051            cmd.arg(key);
1052        }
1053
1054        let reply = self.execute(cmd)?;
1055        <usize>::deserialization(reply)
1056    }
1057
1058    /// Return the position of the first bit set to 1 or 0 in a string.
1059    pub fn bitpos<K>(&mut self, key: K, bit: u8, start: Option<usize>, end: Option<usize>) -> RedisResult<isize>
1060    where
1061        K: RedisSerializationProtocol,
1062    {
1063        if end.is_some() && start.is_none() {
1064            return Err(RedisError::custom(
1065                ErrorKind::ClientError,
1066                "`start` shouldn't be none when `end` has given",
1067            ));
1068        }
1069
1070        let mut cmd = command!("BITPOS"; args => key, bit);
1071        if let Some(start) = start {
1072            cmd.arg(start);
1073        }
1074        if let Some(end) = end {
1075            cmd.arg(end);
1076        }
1077
1078        let reply = self.execute(cmd)?;
1079        <isize>::deserialization(reply)
1080    }
1081
1082    /// Decrements the number stored at key by one.
1083    pub fn decr<K>(&mut self, key: K) -> RedisResult<i64>
1084    where
1085        K: RedisSerializationProtocol,
1086    {
1087        let cmd = command!("DECR"; args => key);
1088        let reply = self.execute(cmd)?;
1089        <i64>::deserialization(reply)
1090    }
1091
1092    /// Decrements the number stored at key by decrement.
1093    pub fn decrby<K>(&mut self, key: K, decrement: i64) -> RedisResult<i64>
1094    where
1095        K: RedisSerializationProtocol,
1096    {
1097        let cmd = command!("DECRBY"; args => key, decrement);
1098        let reply = self.execute(cmd)?;
1099        <i64>::deserialization(reply)
1100    }
1101
1102    /// Get the value of key.
1103    pub fn get<K, V>(&mut self, key: K) -> RedisResult<V>
1104    where
1105        K: RedisSerializationProtocol,
1106        V: RedisDeserializationProtocol,
1107    {
1108        let cmd = command!("GET"; args => key);
1109        let reply = self.execute(cmd)?;
1110        <V>::deserialization(reply)
1111    }
1112
1113    /// Returns the bit value at offset in the string value stored at key.
1114    pub fn getbit<K>(&mut self, key: K, offset: i64) -> RedisResult<u8>
1115    where
1116        K: RedisSerializationProtocol,
1117    {
1118        let cmd = command!("GETBIT"; args => key, offset);
1119        let reply = self.execute(cmd)?;
1120        <u8>::deserialization(reply)
1121    }
1122
1123    /// Returns the substring of the string value stored at key, determined by the offsets start and end (both are inclusive).
1124    pub fn getrange<K>(&mut self, key: K, start: i64, end: i64) -> RedisResult<String>
1125    where
1126        K: RedisSerializationProtocol,
1127    {
1128        let cmd = command!("GETRANGE"; args => key, start, end);
1129        let reply = self.execute(cmd)?;
1130        <String>::deserialization(reply)
1131    }
1132
1133    /// Atomically sets key to value and returns the old value stored at key.
1134    pub fn getset<K, V>(&mut self, key: K, value: V) -> RedisResult<String>
1135    where
1136        K: RedisSerializationProtocol,
1137        V: ToString,
1138    {
1139        let cmd = command!("GETSET"; args => key, value.to_string());
1140        let reply = self.execute(cmd)?;
1141        <String>::deserialization(reply)
1142    }
1143
1144    /// Increments the number stored at key by one.
1145    pub fn incr<K>(&mut self, key: K) -> RedisResult<i64>
1146    where
1147        K: RedisSerializationProtocol,
1148    {
1149        let cmd = command!("INCR"; args => key);
1150        let reply = self.execute(cmd)?;
1151        <i64>::deserialization(reply)
1152    }
1153
1154    /// Increments the number stored at key by increment.
1155    pub fn incrby<K>(&mut self, key: K, increment: i64) -> RedisResult<i64>
1156    where
1157        K: RedisSerializationProtocol,
1158    {
1159        let cmd = command!("INCRBY"; args => key, increment);
1160        let reply = self.execute(cmd)?;
1161        <i64>::deserialization(reply)
1162    }
1163
1164    /// Increment the string representing a floating point number stored at key by the specified increment.
1165    pub fn incrbyfloat<K>(&mut self, key: K, increment: f64) -> RedisResult<f64>
1166    where
1167        K: RedisSerializationProtocol,
1168    {
1169        let cmd = command!("INCRBYFLOAT"; args => key, increment);
1170        let reply = self.execute(cmd)?;
1171        <f64>::deserialization(reply)
1172    }
1173
1174    /// Returns the values of all specified keys.
1175    pub fn mget<K, V>(&mut self, keys: Vec<K>) -> RedisResult<Vec<V>>
1176    where
1177        K: RedisSerializationProtocol,
1178        V: RedisDeserializationProtocol,
1179    {
1180        let mut cmd = Command::new("MGET");
1181        for key in keys {
1182            cmd.arg(key);
1183        }
1184
1185        let reply = self.execute(cmd)?;
1186        <Vec<V>>::deserialization(reply)
1187    }
1188
1189    /// Sets the given keys to their respective values.
1190    pub fn mset<K, V>(&mut self, kvs: Vec<(K, V)>) -> RedisResult<()>
1191    where
1192        K: RedisSerializationProtocol,
1193        V: RedisSerializationProtocol,
1194    {
1195        let mut cmd = Command::new("MSET");
1196        for (k, v) in kvs {
1197            cmd.arg(k).arg(v);
1198        }
1199
1200        let reply = self.execute(cmd)?;
1201        <()>::deserialization(reply)
1202    }
1203
1204    /// Sets the given keys to their respective values.
1205    pub fn msetnx<K, V>(&mut self, kvs: Vec<(K, V)>) -> RedisResult<()>
1206    where
1207        K: RedisSerializationProtocol,
1208        V: RedisSerializationProtocol,
1209    {
1210        let mut cmd = Command::new("MSETNX");
1211        for (k, v) in kvs {
1212            cmd.arg(k).arg(v);
1213        }
1214
1215        let reply = self.execute(cmd)?;
1216        <()>::deserialization(reply)
1217    }
1218
1219    /// PSETEX works exactly like SETEX with the sole difference that the expire time is specified in milliseconds instead of seconds.
1220    pub fn psetex<K, V>(&mut self, key: K, milliseconds: u64, value: V) -> RedisResult<()>
1221    where
1222        K: RedisSerializationProtocol,
1223        V: RedisSerializationProtocol,
1224    {
1225        let cmd = command!("PSETEX"; args => key, milliseconds, value);
1226        let reply = self.execute(cmd)?;
1227        <()>::deserialization(reply)
1228    }
1229
1230    /// Set key to hold the string value.
1231    pub fn set<K, V>(
1232        &mut self,
1233        key: K,
1234        value: V,
1235        ex_seconds: Option<u64>,
1236        px_milliseconds: Option<u64>,
1237        nx: Option<bool>,
1238        xx: Option<bool>,
1239    ) -> RedisResult<()>
1240    where
1241        K: RedisSerializationProtocol,
1242        V: RedisSerializationProtocol,
1243    {
1244        let mut cmd = command!("SET"; args => key, value);
1245        if let Some(ex) = ex_seconds {
1246            cmd.arg("EX").arg(ex);
1247        }
1248        if let Some(px) = px_milliseconds {
1249            cmd.arg("PX").arg(px);
1250        }
1251        if let Some(nx) = nx {
1252            if nx {
1253                cmd.arg("NX");
1254            }
1255        }
1256        if let Some(xx) = xx {
1257            if xx {
1258                cmd.arg("XX");
1259            }
1260        }
1261
1262        let reply = self.execute(cmd)?;
1263        <()>::deserialization(reply)
1264    }
1265
1266    /// Set key to hold the string value.
1267    pub fn simple_set<K, V>(&mut self, key: K, value: V) -> RedisResult<()>
1268    where
1269        K: RedisSerializationProtocol,
1270        V: RedisSerializationProtocol,
1271    {
1272        self.set(key, value, None, None, None, None)
1273    }
1274
1275    /// Sets or clears the bit at offset in the string value stored at key.
1276    pub fn setbit<K>(&mut self, key: K, offset: usize, value: u8) -> RedisResult<u8>
1277    where
1278        K: RedisSerializationProtocol,
1279    {
1280        let cmd = command!("SETBIT"; args => key, offset, value);
1281        let reply = self.execute(cmd)?;
1282        <u8>::deserialization(reply)
1283    }
1284
1285    /// Set key to hold the string value and set key to timeout after a given number of seconds.
1286    pub fn setex<K, V>(&mut self, key: K, seconds: usize, value: V) -> RedisResult<()>
1287    where
1288        K: RedisSerializationProtocol,
1289        V: RedisSerializationProtocol,
1290    {
1291        let cmd = command!("SETEX"; args => key, seconds, value);
1292        let reply = self.execute(cmd)?;
1293        <()>::deserialization(reply)
1294    }
1295
1296    /// Set key to hold string value if key does not exist.
1297    pub fn setnx<K, V>(&mut self, key: K, value: V) -> RedisResult<bool>
1298    where
1299        K: RedisSerializationProtocol,
1300        V: RedisSerializationProtocol,
1301    {
1302        let cmd = command!("SETNX"; args => key, value);
1303        let reply = self.execute(cmd)?;
1304        <bool>::deserialization(reply)
1305    }
1306
1307    /// Overwrites part of the string stored at key, starting at the specified offset, for the entire length of value.
1308    pub fn setrange<K, V>(&mut self, key: K, offset: usize, value: V) -> RedisResult<usize>
1309    where
1310        K: RedisSerializationProtocol,
1311        V: RedisSerializationProtocol,
1312    {
1313        let cmd = command!("SETRANGE"; args => key, offset, value);
1314        let reply = self.execute(cmd)?;
1315        <usize>::deserialization(reply)
1316    }
1317
1318    /// Returns the length of the string value stored at key.
1319    pub fn strlen<K>(&mut self, key: K) -> RedisResult<u64>
1320    where
1321        K: RedisSerializationProtocol,
1322    {
1323        let cmd = command!("STRLEN"; args => key);
1324        let reply = self.execute(cmd)?;
1325        <u64>::deserialization(reply)
1326    }
1327
1328    fn execute(&mut self, cmd: Command) -> RedisResult<Reply> {
1329        let mut conn = self.pool.get()?;
1330        conn.send(&cmd.into_vec())?;
1331        let reply = conn.receive()?;
1332        self.pool.put(conn);
1333        Ok(reply)
1334    }
1335}