Skip to main content

dicedb_rs/
commandrpc.rs

1use crate::client::Client;
2use crate::commands::Command;
3use crate::commands::CommandExecutor;
4use crate::commands::DelInput;
5use crate::commands::ExpireAtOption;
6use crate::commands::ExpireOption;
7use crate::commands::GetexOption;
8use crate::commands::HSetInput;
9use crate::commands::HSetValue;
10use crate::commands::ScalarValue;
11use crate::commands::SetInput;
12use crate::commands::SetOption;
13use crate::errors::StreamError;
14
15type Result<T> = std::result::Result<T, StreamError>;
16
17impl<'a> Into<DelInput<'a>> for Vec<&'a str> {
18    fn into(self) -> DelInput<'a> {
19        DelInput::Multiple(self)
20    }
21}
22
23impl<'a> Into<DelInput<'a>> for &'a str {
24    fn into(self) -> DelInput<'a> {
25        DelInput::Single(self)
26    }
27}
28
29impl<'a> Into<HSetInput<'a>> for (&'a str, &'a str) {
30    fn into(self) -> HSetInput<'a> {
31        HSetInput::Single(self.0, self.1)
32    }
33}
34
35impl<'a> Into<HSetInput<'a>> for Vec<(&'a str, &'a str)> {
36    fn into(self) -> HSetInput<'a> {
37        HSetInput::Multiple(self)
38    }
39}
40
41impl Client {
42    /// Decrements the integer at `key` by one. Creates `key` as -1 if absent. Errors on wrong type
43    /// or non-integer string. Limited to 64-bit signed integers.
44    ///
45    /// # Arguments
46    /// * `key` - The key to decrement.
47    /// # Returns
48    /// * [`Value`] - The new value of `key`.
49    /// # Errors
50    /// * [`StreamError`] - If an error occured in the communication stream.
51    pub fn decr(&mut self, key: &str) -> Result<ScalarValue> {
52        let resp = self.command_client.execute_scalar_command(Command::DECR {
53            key: key.to_string(),
54        })?;
55        Ok(resp)
56    }
57    // DECRBY command decrements the integer at ‘key’ by the delta specified. Creates ‘key’ with value (-delta) if absent. Errors on wrong type or non-integer string. Limited to 64-bit signed integers.
58    /// Decrements the integer at `key` by `delta`. Creates `key` as `-delta` if absent. Errors on
59    /// wrong type
60    /// or non-integer string. Limited to 64-bit signed integers.
61    /// # Arguments
62    /// * `key` - The key to decrement.
63    /// * `delta` - The amount to decrement by.
64    /// # Returns
65    /// * [`Value`] - The new value of `key`.
66    /// # Errors
67    /// * [`StreamError`] - If an error occured in the communication stream.
68    pub fn decrby(&mut self, key: &str, delta: i64) -> Result<ScalarValue> {
69        let resp = self
70            .command_client
71            .execute_scalar_command(Command::DECRBY {
72                key: key.to_string(),
73                delta,
74            })?;
75        Ok(resp)
76    }
77
78    // DEL command deletes all the specified keys and returns the number of keys deleted on success. &
79    /// Deletes all the specified keys and returns the number of keys deleted on success.
80    /// # Arguments
81    /// * `keys` - The keys to delete, either a single key or multiple keys.
82    /// # Returns
83    /// * [`Value`] - The number of keys deleted.
84    /// # Errors
85    /// * [`StreamError`] - If an error occured in the communication stream.
86    pub fn del<'a, T: Into<DelInput<'a>>>(&mut self, keys: T) -> Result<ScalarValue> {
87        let del_input: DelInput<'_> = keys.into();
88        let keys = match del_input {
89            DelInput::Single(key) => vec![key].iter().map(|&x| x.to_string()).collect(),
90            DelInput::Multiple(keys) => keys.iter().map(|&x| x.to_string()).collect(),
91        };
92        let resp = self
93            .command_client
94            .execute_scalar_command(Command::DEL { keys })?;
95        Ok(resp)
96    }
97
98    /// Echos a message with the server, ie. returns the message passed to it.
99    /// # Arguments
100    /// * `message` - The message to return.
101    /// # Returns
102    /// * [`Value`] - The message.
103    /// # Errors
104    /// * [`StreamError`] - If an error occured in the communication stream.
105    pub fn echo(&mut self, message: &str) -> Result<ScalarValue> {
106        let resp = self.command_client.execute_scalar_command(Command::ECHO {
107            message: message.to_string(),
108        })?;
109        Ok(resp)
110    }
111
112    /// Checks if the specified keys exist.
113    /// # Arguments
114    /// * `key` - The key to check.
115    /// * `additional_keys` - Additional keys to check. If empty, only `key` is checked.
116    /// # Returns
117    /// * [`Value`] - The number of keys that exist.
118    /// # Errors
119    /// * [`StreamError`] - If an error occured in the communication stream.
120    pub fn exists(&mut self, key: &str, additional_keys: Vec<&str>) -> Result<ScalarValue> {
121        let resp = self
122            .command_client
123            .execute_scalar_command(Command::EXISTS {
124                key: key.to_string(),
125                additional_keys: additional_keys.iter().map(|&x| x.to_string()).collect(),
126            })?;
127        Ok(resp)
128    }
129    // EXPIRE sets an expiry (in seconds) on a specified key. After the expiry time has elapsed, the key will be automatically deleted.
130    //
131    //     If you want to delete the expirtation time on the key, you can use the PERSIST command.
132    //
133    // The command returns 1 if the expiry was set, and 0 if the key already had an expiry set. The command supports the following options:
134    //
135    //     NX: Set the expiration only if the key does not already have an expiration time.
136    //     XX: Set the expiration only if the key already has an expiration time.
137    //
138    /// Sets an expiry (in seconds) on a specified key. After the expiry time has elapsed, the key
139    /// will be automatically deleted.
140    /// # Arguments
141    /// * `key` - The key to set the expiry on.
142    /// * `seconds` - The number of seconds until the key expires.
143    /// * `option`: [`ExpireOption`] - The option to specify conditions for setting the expiry.
144    /// # Returns
145    /// * [`Value`] - 1 if the expiry was set, 0 if expire was not set.
146    /// # Errors
147    /// * [`StreamError`] - If an error occured in the communication stream.
148    pub fn expire(&mut self, key: &str, seconds: i64, option: ExpireOption) -> Result<ScalarValue> {
149        let resp = self
150            .command_client
151            .execute_scalar_command(Command::EXPIRE {
152                key: key.to_string(),
153                seconds,
154                option,
155            })?;
156        Ok(resp)
157    }
158
159    /// Sets the expiration time of a key as an absolute Unix timestamp (in seconds). After the
160    /// expiry
161    /// time has elapsed, the key will be automatically deleted.
162    /// # Arguments
163    /// * `key` - The key to set the expiry on.
164    /// * `timestamp` - The Unix timestamp in seconds.
165    /// * `option`: [`ExpireAtOption`] - The option to specify conditions for setting the expiry.
166    /// # Returns
167    /// * [`Value`] - 1 if the expiry was set or updated, 0 if the expiration time was not changed.
168    /// # Errors
169    /// * [`StreamError`] - If an error occured in the communication stream.
170    pub fn expireat(
171        &mut self,
172        key: &str,
173        timestamp: i64,
174        option: ExpireAtOption,
175    ) -> Result<ScalarValue> {
176        let resp = self
177            .command_client
178            .execute_scalar_command(Command::EXPIREAT {
179                key: key.to_string(),
180                timestamp,
181                option,
182            })?;
183        Ok(resp)
184    }
185
186    /// Returns the absolute Unix timestamp in seconds at which the given key will expire.
187    /// # Arguments
188    /// * `key` - The key to get the expiry time of.
189    /// # Returns
190    /// * [`Value`] - The Unix timestamp in seconds.
191    /// # Errors
192    /// * [`StreamError`] - If an error occured in the communication stream.
193    pub fn expiretime(&mut self, key: &str) -> Result<ScalarValue> {
194        let resp = self
195            .command_client
196            .execute_scalar_command(Command::EXPIRETIME {
197                key: key.to_string(),
198            })?;
199        Ok(resp)
200    }
201
202    /// Deletes all keys present in the database.
203    pub fn flushdb(&mut self) -> Result<ScalarValue> {
204        let resp = self
205            .command_client
206            .execute_scalar_command(Command::FLUSHDB)?;
207        Ok(resp)
208    }
209    // GET returns the value for the key in args.
210    //
211    // The command returns (nil) if the key does not exist.
212    /// Returns the value for the given key.
213    /// # Arguments
214    /// * `key` - The key to get the value of.
215    /// # Returns
216    /// * [`Value`] - The value of the key. Returns a valid  [`Value::VNull`] variant if the key does not exist.
217    /// # Errors
218    /// * [`StreamError`] - If an error occured in the communication stream.
219    pub fn get(&mut self, key: &str) -> Result<ScalarValue> {
220        let resp = self.command_client.execute_scalar_command(Command::GET {
221            key: key.to_string(),
222        })?;
223        Ok(resp)
224    }
225    /// Returns the value for the given key and then deletes the key.
226    /// # Arguments
227    /// * `key` - The key to get the value of and delete.
228    /// # Returns
229    /// * [`Value`] - The value of the key. Returns a valid  [`Value::VNull`] variant if the key
230    /// does not exist.
231    pub fn getdel(&mut self, key: &str) -> Result<ScalarValue> {
232        let resp = self
233            .command_client
234            .execute_scalar_command(Command::GETDEL {
235                key: key.to_string(),
236            })?;
237        Ok(resp)
238    }
239
240    /// Returns the value for the given key and optionally sets its expiration.
241    /// # Arguments
242    /// * `key` - The key to get the value of.
243    /// * `option`: [`GetexOption`] - The option to specify conditions for setting the expiry.
244    /// # Returns
245    /// * [`Value`] - The value of the key. Returns a valid  [`Value::VNull`] variant if the key
246    /// does not exist.
247    /// # Errors
248    /// * [`StreamError`] - If an error occured in the communication stream.
249    pub fn getex(&mut self, key: &str, option: GetexOption) -> Result<ScalarValue> {
250        let resp = self.command_client.execute_scalar_command(Command::GETEX {
251            key: key.to_string(),
252            ex: option,
253        })?;
254        Ok(resp)
255    }
256    /// Increments the integer at `key` by one. Creates `key` as 1 if absent.    
257    /// /// # Arguments
258    /// * `key` - The key to increment.
259    /// # Returns
260    /// * [`Value`] - The new value of `key`.
261    /// # Errors
262    /// * [`StreamError`] - If an error occured in the communication stream, or if the key is not
263    /// an integer.
264    pub fn incr(&mut self, key: &str) -> Result<ScalarValue> {
265        let resp = self.command_client.execute_scalar_command(Command::INCR {
266            key: key.to_string(),
267        })?;
268        Ok(resp)
269    }
270    /// Increments the integer at `key` by `delta`. Creates `key` as `delta` if absent.
271    /// # Arguments
272    /// * `key` - The key to increment.
273    /// * `delta` - The amount to increment by.
274    /// # Returns
275    /// * [`Value`] - The new value of `key`, or an error if the key is not an integer.
276    pub fn incrby(&mut self, key: &str, delta: i64) -> Result<ScalarValue> {
277        let resp = self
278            .command_client
279            .execute_scalar_command(Command::INCRBY {
280                key: key.to_string(),
281                delta,
282            })?;
283        Ok(resp)
284    }
285    /// Returns PONG if no argument is provided, otherwise it returns PONG with the message
286    /// argument.
287    /// # Returns
288    /// * [`Value`] - The response from the server, with PONG if no argument is provided.
289    /// # Errors
290    /// * [`StreamError`] - If an error occured in the communication stream.
291    pub fn ping(&mut self) -> Result<ScalarValue> {
292        let resp = self.command_client.execute_scalar_command(Command::PING)?;
293        Ok(resp)
294    }
295    /// Sets the value of a key.
296    /// # Arguments
297    /// * `key` - The key to set the value of.
298    /// * `value` - The value to set.
299    /// # Returns
300    /// * [`Value`] - A response from the server with an OK if succes.
301    /// # Errors
302    /// * [`StreamError`] - If an error occured in the communication stream.
303    pub fn set<T: Into<SetInput>>(&mut self, key: &str, value: T) -> Result<ScalarValue> {
304        let resp = self.command_client.execute_scalar_command(Command::SET {
305            key: key.to_string(),
306            value: value.into(),
307            option: crate::commands::SetOption::None,
308            get: false,
309        })?;
310        Ok(resp)
311    }
312
313    /// Sets the value of a key and returns the previous value.
314    /// # Arguments
315    /// * `key` - The key to set the value of.
316    /// * `value` - The value to set.
317    /// # Returns
318    /// * [`Value`] - The previous value of the key.
319    /// # Errors
320    /// * [`StreamError`] - If an error occured in the communication stream.
321    pub fn setget<T: Into<SetInput>>(&mut self, key: &str, value: T) -> Result<ScalarValue> {
322        let resp = self.command_client.execute_scalar_command(Command::SET {
323            key: key.to_string(),
324            value: value.into(),
325            option: crate::commands::SetOption::None,
326            get: true,
327        })?;
328        Ok(resp)
329    }
330
331    /// Sets the value of a field in a set for a key.
332    /// Yields a OK result if operation went okay, and an integer value for number of fields
333    /// updated.
334    ///
335    /// # Arguments
336    /// * `key` - The key to set the value of.
337    /// * `fields` - The fields to set.
338    /// # Returns
339    /// * [`Value`] - A response from the server with an OK if succes and the number of updated
340    /// fields.
341    /// # Errors
342    /// * [`StreamError`] - If an error occured in the communication stream.
343    pub fn hset<'a, T: Into<HSetInput<'a>>>(
344        &mut self,
345        key: &str,
346        fields: T,
347    ) -> Result<ScalarValue> {
348        let hset_input: HSetInput<'_> = fields.into();
349        let fields: Vec<(String, String)> = match hset_input {
350            HSetInput::Single(field, value) => vec![(field.to_string(), value.to_owned())],
351            HSetInput::Multiple(fields) => fields
352                .iter()
353                .map(|(f, v)| (f.to_string(), v.to_string()))
354                .collect(),
355        };
356        let resp = self.command_client.execute_scalar_command(Command::HSET {
357            key: key.to_string(),
358            fields,
359        })?;
360        Ok(resp)
361    }
362
363    /// Gets the value of a field in a set for a key.
364    /// # Arguments
365    /// * `key` - The key to get the value of.
366    /// * `field` - The field to get the value of.
367    /// # Returns
368    /// * [`Value`] - The value of the field, VNull if the field does not exist.
369    /// # Errors
370    /// * [`StreamError`] - If an error occured in the communication stream.
371    pub fn hget(&mut self, key: &str, field: &str) -> Result<ScalarValue> {
372        let resp = self.command_client.execute_scalar_command(Command::HGET {
373            key: key.to_string(),
374            field: field.to_string(),
375        })?;
376        Ok(resp)
377    }
378
379    /// Gets all fields for a set for a key.
380    /// # Arguments
381    /// * `key` - The key to get the fields of.
382    /// # Returns
383    /// * [`Value`] - A list of fields and their values. TODO: Probalby wrong
384    /// # Errors
385    /// * [`StreamError`] - If an error occured in the communication stream.
386    pub fn hgetall(&mut self, key: &str) -> Result<HSetValue> {
387        let resp = self.command_client.execute_hset_command(Command::HGETALL {
388            key: key.to_string(),
389        })?;
390        Ok(resp)
391    }
392
393    /// Sets the value of a key with an expiration time.
394    /// # Arguments
395    /// * `key` - The key to set the value of.
396    /// * `value` - The value to set.
397    /// * `option`: [`SetOption`] - The option to specify conditions for setting the expiry.
398    /// # Returns
399    /// * [`Value`] - A response from the server with an OK if succes.
400    /// # Errors
401    /// * [`StreamError`] - If an error occured in the communication stream.
402    pub fn setex<T: Into<SetInput>>(
403        &mut self,
404        key: &str,
405        value: T,
406        option: SetOption,
407    ) -> Result<ScalarValue> {
408        let resp = self.command_client.execute_scalar_command(Command::SET {
409            key: key.to_string(),
410            value: value.into(),
411            option,
412            get: false,
413        })?;
414        Ok(resp)
415    }
416    /// Returns the remaining time to live (in seconds) of a key that has an expiration set.
417    /// # Arguments
418    /// * `key` - The key to get the time to live of.
419    /// # Returns
420    /// * [`Value`] - The remaining time to live in seconds.
421    /// # Errors
422    /// * [`StreamError`] - If an error occured in the communication stream.
423    pub fn ttl(&mut self, key: &str) -> Result<ScalarValue> {
424        let resp = self.command_client.execute_scalar_command(Command::TTL {
425            key: key.to_string(),
426        })?;
427        Ok(resp)
428    }
429
430    /// Returns the type of the value stored at `key` as a string.
431    /// # Arguments
432    /// * `key` - The key to get the type of.
433    /// # Returns
434    /// * [`Value`] - The type of the value stored at `key`, as a [`Value::VStr`] variant.
435    /// # Errors
436    /// * [`StreamError`] - If an error occured in the communication stream.
437    pub fn dtype(&mut self, key: &str) -> Result<ScalarValue> {
438        let resp = self.command_client.execute_scalar_command(Command::TYPE {
439            key: key.to_string(),
440        })?;
441        Ok(resp)
442    }
443}
444
445#[cfg(test)]
446mod tests {
447    use std::collections::HashMap;
448
449    use uuid::Uuid;
450
451    use super::*;
452    const HOST: &str = "localhost";
453    const PORT: u16 = 7379;
454
455    #[test]
456    fn test_key_w_spaces() {
457        // NOTE: Today this is legal, but should it?
458        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
459        let key = "test ilegal key";
460        let value = SetInput::Str("ilegal key?".to_string());
461        let result = client.set(key, value.clone());
462        assert!(result.is_ok());
463        let value_get = client.get(key).unwrap();
464        assert_eq!(value_get, ScalarValue::VStr("ilegal key?".to_string()));
465    }
466
467    #[test]
468    fn test_key_w_underscores() {
469        // NOTE: Today this is legal, but should it?
470        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
471        let key = "test_ilegal_key";
472        let value = SetInput::Str("ilegal key with underscores?".to_string());
473        let result = client.set(key, value.clone());
474        assert!(result.is_ok());
475        let value_get = client.get(key).unwrap();
476        assert_eq!(
477            value_get,
478            ScalarValue::VStr("ilegal key with underscores?".to_string())
479        );
480    }
481
482    #[test]
483    fn test_key_w_newline() {
484        // NOTE: Today this is legal, but should it?
485        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
486        let key = "test\nilegal\nkey";
487        let value = SetInput::Str("ilegal key with newlines?".to_string());
488        let result = client.set(key, value.clone());
489        assert!(result.is_ok());
490        let value_get = client.get(key).unwrap();
491        assert_eq!(
492            value_get,
493            ScalarValue::VStr("ilegal key with newlines?".to_string())
494        );
495    }
496
497    #[test]
498    fn test_key_w_weird_symbols() {
499        // NOTE: Today this is legal, but should it?
500        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
501        let key = "test!@#$«»%^&*()_+\t";
502        let value = SetInput::Str("ilegal key with weird symbols?".to_string());
503        let result = client.set(key, value.clone());
504        assert!(result.is_ok());
505        let value_get = client.get(key).unwrap();
506        assert_eq!(
507            value_get,
508            ScalarValue::VStr("ilegal key with weird symbols?".to_string())
509        );
510    }
511
512    #[test]
513    fn test_key_w_underscores_cause_problems_with_exists() {
514        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
515        let key = "test_ilegal_key_exists";
516        let value = SetInput::Str("ilegal key with underscores?".to_string());
517        let result = client.set(key, value.clone());
518        assert!(result.is_ok());
519        let value_get = client.exists(key, vec![key, key]).unwrap();
520        assert_eq!(value_get, ScalarValue::VInt(9)); // BUG: There is probably a bug with how additional
521                                                     // keys are handled in the exists command.
522    }
523
524    #[test]
525    fn test_case_sensitive_keys() {
526        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
527        let key = "UPPERcase";
528        let value = SetInput::Str("case sensitive key?".to_string());
529        let result = client.set(key, value.clone());
530        assert!(result.is_ok());
531        let get = client.get("uppercase").unwrap();
532        assert_eq!(get, ScalarValue::VNull);
533        let value_get = client.get(key).unwrap();
534        assert_eq!(
535            value_get,
536            ScalarValue::VStr("case sensitive key?".to_string())
537        );
538    }
539
540    #[test]
541    fn test_hgetset_single() {
542        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
543
544        let key = "testhsetint";
545        let field_string = Uuid::new_v4().to_string();
546        let field = field_string.as_str();
547
548        let set_value = "Some value";
549        let result = client.hset(key, (field, set_value)).unwrap();
550        assert_eq!(result, ScalarValue::VInt(1));
551
552        let value_get = client.hget(key, field).unwrap();
553        assert_eq!(value_get, ScalarValue::VStr(set_value.to_string()));
554    }
555
556    #[test]
557    fn test_hgetset_multi() {
558        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
559
560        let key = "testhsetint";
561        let field_string = Uuid::new_v4().to_string();
562        let field = field_string.as_str();
563
564        let field_string2 = Uuid::new_v4().to_string();
565        let field2 = field_string2.as_str();
566
567        let set_value = "Some value";
568        let set_value2 = "Some value 2";
569        let result = client
570            .hset(key, vec![(field, set_value), (field2, set_value2)])
571            .unwrap();
572        assert_eq!(result, ScalarValue::VInt(2));
573
574        let value_get = client.hget(key, field).unwrap();
575        assert_eq!(value_get, ScalarValue::VStr(set_value.to_string()));
576
577        let value_get2 = client.hget(key, field2).unwrap();
578        assert_eq!(value_get2, ScalarValue::VStr(set_value2.to_string()));
579    }
580
581    #[test]
582    fn test_hgetall() {
583        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
584
585        let randomness = Uuid::new_v4().to_string();
586        let key = format!("testhgetall{}", randomness);
587        let kv = vec![
588            ("somefield1", "Some  value1"),
589            ("somefield2", "Some value2"),
590            ("somefield3", "Some value3"),
591        ];
592        let set_result = client.hset(&key, kv).unwrap();
593        assert_eq!(set_result, ScalarValue::VInt(3));
594
595        let hset: HashMap<String, String> = client.hgetall(&key).unwrap().into();
596
597        assert_eq!(hset.len(), 3);
598        assert_eq!(hset.get("somefield1").unwrap(), "Some  value1");
599        assert_eq!(hset.get("somefield2").unwrap(), "Some value2");
600        assert_eq!(hset.get("somefield3").unwrap(), "Some value3");
601    }
602
603    #[test]
604    fn test_decr() {
605        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
606        let key = "testdecr";
607        let value = SetInput::Int(1);
608        client.set(key, value.clone()).unwrap();
609        let result = client.decr(key).unwrap();
610        assert_eq!(result, ScalarValue::VInt(0));
611    }
612
613    #[test]
614    fn test_decrby() {
615        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
616        let key = "testdecrby";
617        let value = SetInput::Int(3);
618        client.set(key, value.clone()).unwrap();
619        let result = client.decrby(key, 2).unwrap();
620        assert_eq!(result, ScalarValue::VInt(1));
621    }
622
623    #[test]
624    fn test_decrby_overflow() {
625        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
626        let key = "testdecrbyoverflow";
627        let value = SetInput::Int(i64::MIN);
628        client.set(key, value.clone()).unwrap();
629        let result = client.decrby(key, 1).unwrap();
630        assert_eq!(result, ScalarValue::VInt(i64::MAX));
631    }
632
633    #[test]
634    fn test_decr_min_underflow() {
635        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
636        let key = "testdecrmin";
637        let value = SetInput::Int(i64::MIN);
638        client.set(key, value.clone()).unwrap();
639        let result = client.decr(key).unwrap();
640        assert_eq!(result, ScalarValue::VInt(i64::MAX));
641    }
642
643    #[test]
644    fn test_del() {
645        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
646        let key = "testdel";
647        let value = SetInput::Str("test".to_string());
648        client.set(key, value.clone()).unwrap();
649        let result = client.del(vec![key]).unwrap();
650        assert_eq!(result, ScalarValue::VInt(1));
651
652        let value_get = client.get(key).unwrap();
653        assert_eq!(value_get, ScalarValue::VNull);
654    }
655
656    #[test]
657    fn test_expire() {
658        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
659        let key = "testexpire";
660        let value = SetInput::Str("test".to_string());
661        client.set(key, value.clone()).unwrap();
662        let result = client.expire(key, 1, ExpireOption::None).unwrap();
663        assert_eq!(result, ScalarValue::VInt(1));
664
665        std::thread::sleep(std::time::Duration::from_secs(2));
666        let value_get = client.get(key).unwrap();
667        assert_eq!(value_get, ScalarValue::VNull);
668    }
669
670    #[test]
671    fn test_expire_nx() {
672        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
673        let key = "testexpirenx";
674        let value = SetInput::Str("test".to_string());
675        client.set(key, value.clone()).unwrap();
676        let result = client.expire(key, 1, ExpireOption::NX).unwrap();
677        assert_eq!(result, ScalarValue::VInt(1));
678
679        let result = client.expire(key, 100, ExpireOption::NX).unwrap();
680        assert_eq!(result, ScalarValue::VInt(0));
681
682        std::thread::sleep(std::time::Duration::from_secs(2));
683        let value_get = client.get(key).unwrap();
684        assert_eq!(value_get, ScalarValue::VNull);
685    }
686
687    #[test]
688    fn test_expire_xx() {
689        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
690        let key = "testexpirexx";
691        let value = SetInput::Str("test".to_string());
692        client.set(key, value.clone()).unwrap();
693
694        let result = client.expire(key, 100, ExpireOption::XX).unwrap();
695        assert_eq!(result, ScalarValue::VInt(0));
696
697        let result = client.expire(key, 100, ExpireOption::None).unwrap();
698        assert_eq!(result, ScalarValue::VInt(1));
699
700        let result = client.expire(key, 1, ExpireOption::XX).unwrap();
701        assert_eq!(result, ScalarValue::VInt(1));
702
703        std::thread::sleep(std::time::Duration::from_secs(3));
704        let value_get = client.get(key).unwrap();
705        assert_eq!(value_get, ScalarValue::VNull);
706    }
707
708    #[test]
709    fn test_existsmany() {
710        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
711        let key1 = "testexistsmany1";
712        client.set(key1, "test").unwrap();
713        let key2 = "testexistsmany2";
714        client.set(key2, "test").unwrap();
715        let key3 = "testexistsmany3";
716        let result = client.exists(key1, vec![key2, key3]).unwrap();
717        assert_eq!(result, ScalarValue::VInt(3));
718    }
719
720    #[test]
721    fn test_exists_one() {
722        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
723        let key1 = "testexists1";
724        client.set(key1, "test").unwrap();
725        let result = client.exists(key1, vec![]).unwrap();
726        assert_eq!(result, ScalarValue::VInt(1));
727    }
728
729    #[test]
730    fn test_exists_two() {
731        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
732        let key1 = "testexiststwo1";
733        client.set(key1, "test").unwrap();
734        let key2 = "testexiststwo2";
735        client.set(key2, "test").unwrap();
736        let result = client.exists(key1, vec![key2]).unwrap();
737        assert_eq!(result, ScalarValue::VInt(2));
738    }
739
740    #[test]
741    fn test_expireat() {
742        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
743        let key = "testexpireat";
744        let value = SetInput::Str("test".to_string());
745        client.set(key, value.clone()).unwrap();
746
747        let timestamp = std::time::SystemTime::now()
748            .duration_since(std::time::UNIX_EPOCH)
749            .unwrap()
750            .as_secs()
751            + 1;
752
753        let result = client
754            .expireat(key, timestamp as i64, ExpireAtOption::None)
755            .unwrap();
756        assert_eq!(result, ScalarValue::VInt(1));
757
758        std::thread::sleep(std::time::Duration::from_secs(2));
759        let value_get = client.get(key).unwrap();
760        assert_eq!(value_get, ScalarValue::VNull);
761    }
762
763    #[test]
764    fn test_expireat_nx() {
765        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
766        let key = "testexpireatnx";
767        let value = SetInput::Str("test".to_string());
768        client.set(key, value.clone()).unwrap();
769
770        let timestamp = std::time::SystemTime::now()
771            .duration_since(std::time::UNIX_EPOCH)
772            .unwrap()
773            .as_secs()
774            + 1;
775
776        let result = client
777            .expireat(key, timestamp as i64, ExpireAtOption::NX)
778            .unwrap();
779        assert_eq!(result, ScalarValue::VInt(1));
780
781        let result = client
782            .expireat(key, timestamp as i64, ExpireAtOption::NX)
783            .unwrap();
784        assert_eq!(result, ScalarValue::VInt(0));
785
786        std::thread::sleep(std::time::Duration::from_secs(2));
787        let value_get = client.get(key).unwrap();
788        assert_eq!(value_get, ScalarValue::VNull);
789    }
790
791    #[test]
792    fn test_expireat_xx() {
793        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
794        let key = "testexpireatxx";
795        let value = SetInput::Str("test".to_string());
796        client.set(key, value.clone()).unwrap();
797
798        let timestamp = std::time::SystemTime::now()
799            .duration_since(std::time::UNIX_EPOCH)
800            .unwrap()
801            .as_secs()
802            + 1;
803
804        let result = client
805            .expireat(key, timestamp as i64, ExpireAtOption::XX)
806            .unwrap();
807        assert_eq!(result, ScalarValue::VInt(0));
808
809        let result = client
810            .expireat(key, timestamp as i64, ExpireAtOption::None)
811            .unwrap();
812        assert_eq!(result, ScalarValue::VInt(1));
813
814        let result = client
815            .expireat(key, timestamp as i64, ExpireAtOption::XX)
816            .unwrap();
817        assert_eq!(result, ScalarValue::VInt(1));
818
819        std::thread::sleep(std::time::Duration::from_secs(2));
820        let value_get = client.get(key).unwrap();
821        assert_eq!(value_get, ScalarValue::VNull);
822    }
823
824    #[test]
825    fn test_expireat_gt() {
826        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
827        let key = "testexpireatgt";
828        let value = SetInput::Str("test".to_string());
829        client.set(key, value.clone()).unwrap();
830
831        let timestamp_2sec = std::time::SystemTime::now()
832            .duration_since(std::time::UNIX_EPOCH)
833            .unwrap()
834            .as_secs()
835            + 2;
836
837        let timestamp_1sec = std::time::SystemTime::now()
838            .duration_since(std::time::UNIX_EPOCH)
839            .unwrap()
840            .as_secs()
841            + 1;
842
843        let result = client
844            .expireat(key, timestamp_2sec as i64, ExpireAtOption::GT)
845            .unwrap();
846        assert_eq!(result, ScalarValue::VInt(0));
847
848        let result = client
849            .expireat(key, timestamp_1sec as i64, ExpireAtOption::None)
850            .unwrap();
851        assert_eq!(result, ScalarValue::VInt(1));
852
853        let result = client
854            .expireat(key, timestamp_2sec as i64, ExpireAtOption::GT)
855            .unwrap();
856        assert_eq!(result, ScalarValue::VInt(1));
857
858        let result = client
859            .expireat(key, timestamp_1sec as i64, ExpireAtOption::GT)
860            .unwrap();
861        assert_eq!(result, ScalarValue::VInt(0));
862    }
863
864    #[test]
865    fn test_expireat_lt() {
866        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
867        let key = "testexpireatlt";
868        let value = SetInput::Str("test".to_string());
869        client.set(key, value.clone()).unwrap();
870
871        let timestamp_2sec = std::time::SystemTime::now()
872            .duration_since(std::time::UNIX_EPOCH)
873            .unwrap()
874            .as_secs()
875            + 2;
876
877        let timestamp_1sec = std::time::SystemTime::now()
878            .duration_since(std::time::UNIX_EPOCH)
879            .unwrap()
880            .as_secs()
881            + 1;
882
883        let result = client
884            .expireat(key, timestamp_1sec as i64, ExpireAtOption::LT)
885            .unwrap();
886        assert_eq!(result, ScalarValue::VInt(0));
887
888        let result = client
889            .expireat(key, timestamp_2sec as i64, ExpireAtOption::None)
890            .unwrap();
891        assert_eq!(result, ScalarValue::VInt(1));
892
893        let result = client
894            .expireat(key, timestamp_1sec as i64, ExpireAtOption::LT)
895            .unwrap();
896        assert_eq!(result, ScalarValue::VInt(1));
897
898        let result = client
899            .expireat(key, timestamp_2sec as i64, ExpireAtOption::LT)
900            .unwrap();
901        assert_eq!(result, ScalarValue::VInt(0));
902    }
903
904    #[test]
905    fn test_expiretime() {
906        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
907        let key = "testexpiretime";
908        let value = SetInput::Str("test".to_string());
909        client.set(key, value.clone()).unwrap();
910        let expire_result = client.expire(key, 1, ExpireOption::None).unwrap();
911        let expire_time = client.expiretime(key).unwrap();
912        assert_eq!(expire_result, ScalarValue::VInt(1));
913        let now_epoch = std::time::SystemTime::now()
914            .duration_since(std::time::UNIX_EPOCH)
915            .unwrap()
916            .as_secs()
917            + 1;
918        assert_eq!(expire_time, ScalarValue::VInt(now_epoch as i64));
919    }
920
921    #[test]
922    #[ignore] // We ignore this test, as it will flush the database and cause other tests to fail
923    fn test_flushdb() {
924        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
925        let key = "testflushdb";
926        let value = SetInput::Str("test".to_string());
927        client.set(key, value.clone()).unwrap();
928        let result = client.flushdb().unwrap();
929        assert_eq!(result, ScalarValue::VStr("OK".to_string()));
930
931        let value_get = client.get(key).unwrap();
932        assert_eq!(value_get, ScalarValue::VNull);
933    }
934
935    #[test]
936    fn test_get_set() {
937        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
938        let key = "testgetset";
939        let value = SetInput::Str("test".to_string());
940        client.set(key, value.clone()).unwrap();
941        let result = client.get(key).unwrap();
942        assert_eq!(result, value.into());
943    }
944
945    #[test]
946    fn test_set_with_get() {
947        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
948        let key = "testsetwithget";
949        let value = SetInput::Str("test".to_string());
950        let result = client.set(key, value.clone()).unwrap();
951        assert_eq!(result, ScalarValue::VStr("OK".to_string()));
952        let new_value = SetInput::Str("new test".to_string());
953        let result = client.setget(key, new_value.clone()).unwrap();
954        assert_eq!(result, value.into());
955    }
956
957    #[test]
958    fn test_ping_pong() {
959        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
960        let result = client.ping().unwrap();
961        assert_eq!(result, ScalarValue::VStr("PONG".to_string()));
962    }
963
964    #[test]
965    fn test_echo() {
966        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
967        let message = "hello";
968        let result = client.echo(message).unwrap();
969        assert_eq!(result, ScalarValue::VStr(message.to_string()));
970    }
971
972    #[test]
973    fn test_getdel() {
974        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
975        let key = "testgetdel";
976        let value = SetInput::Str("test".to_string());
977        client.set(key, value.clone()).unwrap();
978        let result = client.getdel(key).unwrap();
979        assert_eq!(result, value.into());
980
981        let value_get = client.get(key).unwrap();
982        assert_eq!(value_get, ScalarValue::VNull);
983    }
984
985    #[test]
986    fn test_getex() {
987        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
988        let key = "testgetex";
989        let value = SetInput::Str("test".to_string());
990        client.set(key, value.clone()).unwrap();
991        let result = client.getex(key, GetexOption::EX(1)).unwrap();
992        assert_eq!(result, value.into());
993
994        std::thread::sleep(std::time::Duration::from_secs(2));
995
996        let value_get = client.get(key).unwrap();
997        assert_eq!(value_get, ScalarValue::VNull);
998    }
999
1000    #[test]
1001    fn test_incr() {
1002        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1003        let key = "testincr";
1004        let value = SetInput::Int(1);
1005        client.set(key, value.clone()).unwrap();
1006        let result = client.incr(key).unwrap();
1007        assert_eq!(result, ScalarValue::VInt(2));
1008    }
1009
1010    #[test]
1011    fn test_incrby() {
1012        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1013        let key = "testincrby";
1014        let value = SetInput::Int(1);
1015        client.set(key, value.clone()).unwrap();
1016        let result = client.incrby(key, 2).unwrap();
1017        assert_eq!(result, ScalarValue::VInt(3));
1018    }
1019
1020    #[test]
1021    fn test_incr_overflow() {
1022        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1023        let key = "testincroverflow";
1024        let value = SetInput::Int(i64::MAX);
1025        client.set(key, value.clone()).unwrap();
1026        let result = client.incr(key).unwrap();
1027        assert_eq!(result, ScalarValue::VInt(i64::MIN));
1028    }
1029
1030    #[test]
1031    fn test_ttl() {
1032        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1033        let key = "testttl";
1034        let value = SetInput::Str("test".to_string());
1035        let result = client.setex(key, value.clone(), SetOption::EX(1)).unwrap();
1036        assert_eq!(result, ScalarValue::VStr("OK".to_string()));
1037        let ttl = client.ttl(key).unwrap();
1038        // This test is susceptible to failing for timing reasons if not given a acceptable range
1039        let withinacceptable = match ttl {
1040            ScalarValue::VInt(v) if v <= 2 && v >= 0 => true,
1041            _ => false,
1042        };
1043        assert_eq!(withinacceptable, true);
1044    }
1045
1046    #[test]
1047    fn test_type_str() {
1048        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1049        let key = "testtypestr";
1050        let value = SetInput::Str("test".to_string());
1051        client.set(key, value.clone()).unwrap();
1052        let result = client.dtype(key).unwrap();
1053        assert_eq!(result, ScalarValue::VStr("string".to_string()));
1054    }
1055
1056    #[test]
1057    fn test_type_int() {
1058        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1059        let key = "testtypeint";
1060        let value = SetInput::Int(1);
1061        client.set(key, value.clone()).unwrap();
1062        let result = client.dtype(key).unwrap();
1063        assert_eq!(result, ScalarValue::VStr("int".to_string()));
1064    }
1065
1066    #[test]
1067    fn test_type_null() {
1068        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1069        let key = "testtypenull";
1070        let result = client.dtype(key).unwrap();
1071        assert_eq!(result, ScalarValue::VStr("none".to_string()));
1072    }
1073
1074    #[test]
1075    fn test_type_float() {
1076        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1077        let key = "testtypefloat";
1078        let value = SetInput::Float(1.3);
1079        client.set(key, value.clone()).unwrap();
1080        let result = client.dtype(key).unwrap();
1081        assert_eq!(result, ScalarValue::VStr("float".to_string()));
1082    }
1083
1084    #[test]
1085    fn test_get_set_float() {
1086        let mut client = Client::new(HOST.to_string(), PORT).unwrap();
1087        let key = "testgetsetfloat";
1088        let value = SetInput::Float(1.3);
1089        client.set(key, value.clone()).unwrap();
1090        let result = client.get(key);
1091        assert!(result.is_err()); // BUG: Known bug, cant get float values atm.
1092    }
1093}