rustdis/commands/
getdel.rs

1use std::sync::{Arc, Mutex};
2
3use crate::commands::executable::Executable;
4use crate::commands::CommandParser;
5use crate::frame::Frame;
6use crate::store::Store;
7use crate::Error;
8
9/// Get the value of key and delete the key. This command is similar to GET, except for the fact
10/// that it also deletes the key on success (if and only if the key's value type is a string).
11///
12/// Ref: <https://redis.io/docs/latest/commands/getdel/>
13#[derive(Debug, PartialEq)]
14pub struct Getdel {
15    pub key: String,
16}
17
18impl Executable for Getdel {
19    fn exec(self, store: Arc<Mutex<Store>>) -> Result<Frame, Error> {
20        let mut store = store.lock().unwrap();
21        let removed_key = store.remove(&self.key);
22        let res = match removed_key {
23            Some(val) => Frame::Bulk(val),
24            None => Frame::Null,
25        };
26
27        Ok(res)
28    }
29}
30
31impl TryFrom<&mut CommandParser> for Getdel {
32    type Error = Error;
33
34    fn try_from(parser: &mut CommandParser) -> Result<Self, Self::Error> {
35        let key = parser.next_string()?;
36        Ok(Self { key })
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use bytes::Bytes;
43
44    use crate::commands::Command;
45
46    use super::*;
47
48    #[test]
49    fn when_key_exists() {
50        let store = Arc::new(Mutex::new(Store::default()));
51
52        let frame = Frame::Array(vec![
53            Frame::Bulk(Bytes::from("GETDEL")),
54            Frame::Bulk(Bytes::from("foo")),
55        ]);
56        let cmd = Command::try_from(frame).unwrap();
57        assert_eq!(
58            cmd,
59            Command::Getdel(Getdel {
60                key: "foo".to_string()
61            })
62        );
63
64        store
65            .lock()
66            .unwrap()
67            .set("foo".to_string(), Bytes::from("baz"));
68
69        let res = cmd.exec(store.clone()).unwrap();
70        assert_eq!(res, Frame::Bulk(Bytes::from("baz")));
71        assert_eq!(store.lock().unwrap().get("foo"), None);
72    }
73
74    #[test]
75    fn when_key_does_not_exists() {
76        let store = Arc::new(Mutex::new(Store::default()));
77
78        let frame = Frame::Array(vec![
79            Frame::Bulk(Bytes::from("GETDEL")),
80            Frame::Bulk(Bytes::from("foo")),
81        ]);
82        let cmd = Command::try_from(frame).unwrap();
83        assert_eq!(
84            cmd,
85            Command::Getdel(Getdel {
86                key: "foo".to_string()
87            })
88        );
89
90        let res = cmd.exec(store.clone()).unwrap();
91        assert_eq!(res, Frame::Null);
92    }
93}