gandolf_kvs/
command.rs

1use crate::{Frame, Parse, Db, Connection};
2
3use bytes::Bytes;
4
5use tracing::debug;
6
7#[derive(Debug)]
8pub enum Command {
9    Get(Get),
10    Set(Set),
11    Load(Load),
12    Snap(Snap)
13}
14
15
16#[derive(Debug)]
17pub struct Get {
18    key: String,
19}
20
21#[derive(Debug)]
22pub struct Set {
23    key: String,
24    value: Bytes,
25}
26
27#[derive(Debug)]
28pub struct Load {
29    elements: Vec<Set>
30}
31
32#[derive(Debug)]
33pub struct Snap;
34
35impl Command {
36    pub fn from_frame(frame: Frame) -> crate::Result<Command> {
37        let mut parse = Parse::new(frame)?;
38
39        let cmd_name = parse.next_string()?.to_lowercase();
40
41        debug!("cmd name is {:?}", cmd_name);
42
43        let cmd = match &cmd_name[..] {
44            "get" => Command::Get(Get::from_parse(&mut parse)?),
45            "set" => Command::Set(Set::from_parse(&mut parse)?),
46            "load" => Command::Load(Load::from_parse(&mut parse)?),
47            "snap" => Command::Snap(Snap),
48            _ => {
49                return Err("Could not parse the command".into())
50            }
51        };
52
53        parse.finish()?;
54        return Ok(cmd);
55    }
56
57
58    pub async fn apply(self, db: &Db, con: &mut Connection) -> crate::Result<()>{
59        match self {
60            Command::Get(cmd) => cmd.apply(db, con).await,
61            Command::Set(cmd) => cmd.apply(db, con).await,
62            Command::Load(cmd) => cmd.apply(db, con).await,
63            Command::Snap(cmd) => cmd.apply(db, con).await,
64        }
65    }
66}
67
68impl Load {
69    pub fn from_parse(parse: &mut Parse) -> crate::Result<Load> {
70        debug!("parse is {:?}", parse);
71        let mut elements = Vec::new();
72        let mut els = parse.next_array()?;
73        while let Ok(mut p) = els.next_array() {
74            let set = Set::from_parse(&mut p)?;
75            elements.push(set);
76        }
77        Ok(Load {
78            elements
79        })
80    }
81
82    pub async fn apply(self, db: &Db, con: &mut Connection) -> crate::Result<()> {
83        for set in self.elements.into_iter() {
84            db.set(set.key, set.value);
85        }
86        let response = Frame::Simple("OK".into());
87        con.write_frame(&response).await?;
88
89        Ok(())
90    }
91}
92
93impl Snap {
94    pub async fn apply(self, db: &Db, con: &mut Connection) -> crate::Result<()> {
95        let kv = db.snap();
96        let mut load = Vec::new();
97        let mut elements = Vec::new();
98
99        //Array([Simple("load"), Array([Array([Simple("a"), Bulk(b"asdfq")]), Array([Simple("b"), Bulk(b"asd")])])] 
100        for (k, v) in kv.into_iter() {
101            let el = vec![Frame::Simple(k), Frame::Bulk(v.data)];
102            elements.push(Frame::Array(el));
103        }
104
105        load.push(Frame::Simple("load".to_string()));
106        load.push(Frame::Array(elements));
107
108        con.write_frame(&Frame::Array(load)).await?;
109
110        Ok(())
111    }
112}
113
114impl Get {
115    pub fn new(key: String) -> Get {
116        Get {
117            key: key.to_string()
118        }
119    }
120
121    pub fn from_parse(parse: &mut Parse) -> crate::Result<Get> {
122        let key = parse.next_string()?;
123        Ok(Get {
124            key: key
125        })
126    }
127
128    pub fn key(&self) -> &str {
129        &self.key
130    }
131
132    pub async fn apply(self, db: &Db, con: &mut Connection) -> crate::Result<()> {
133        let response = if let Some(value) = db.get(&self.key) {
134            Frame::Bulk(value)
135        } else {
136            Frame::Null
137        };
138
139        debug!(?response);
140        con.write_frame(&response).await?;
141
142        Ok(())
143    }
144
145    pub fn into_frame(self) -> Frame {
146        let name = Frame::Bulk(Bytes::from("get".as_bytes()));
147        let key = Frame::Bulk(Bytes::from(self.key.into_bytes()));
148        Frame::Array(vec![name, key])
149    }
150
151}
152
153
154impl Set {
155    pub fn new(key: impl ToString, value: Bytes) -> Set {
156        Set {
157            key: key.to_string(),
158            value: value
159        }
160    }
161
162    pub fn from_parse(parse: &mut Parse) -> crate::Result<Set> {
163        let key = parse.next_string()?;
164        let value = parse.next_bytes()?;
165        Ok(Set {
166            key: key,
167            value: value
168        })
169    }
170
171    pub async fn apply(self, db: &Db, con: &mut Connection) -> crate::Result<()>{
172        db.set(self.key, self.value);
173        let response = Frame::Simple("OK".into());
174
175        debug!(?response);
176        con.write_frame(&response).await?;
177
178        Ok(())
179    }
180
181    pub fn into_frame(self) -> Frame {
182        let name = Frame::Bulk(Bytes::from("set".as_bytes()));
183        let key = Frame::Bulk(Bytes::from(self.key.into_bytes()));
184        let value = Frame::Bulk(Bytes::from(self.value));
185        Frame::Array(vec![name, key, value])
186    }
187
188    pub fn key(&self) -> &str {
189        &self.key
190    }
191
192    pub fn value(&self) -> &Bytes {
193        &self.value
194    }
195}