1use std::sync::{Arc, Mutex};
2
3use bytes::Bytes;
4
5use crate::commands::executable::Executable;
6use crate::commands::{CommandParser, CommandParserError};
7use crate::frame::Frame;
8use crate::store::Store;
9use crate::Error;
10
11#[derive(Debug, PartialEq)]
15pub struct Mset {
16 pub pairs: Vec<(String, Bytes)>,
17}
18
19impl Executable for Mset {
20 fn exec(self, store: Arc<Mutex<Store>>) -> Result<Frame, Error> {
21 if self.pairs.is_empty() {
22 return Ok(Frame::Error(
23 "ERR wrong number of arguments for command".to_string(),
24 ));
25 }
26
27 let mut store = store.lock().unwrap();
28
29 for (key, value) in self.pairs.iter() {
30 store.set(key.to_string(), value.clone());
31 }
32
33 Ok(Frame::Simple("OK".to_string()))
34 }
35}
36
37impl TryFrom<&mut CommandParser> for Mset {
38 type Error = Error;
39
40 fn try_from(parser: &mut CommandParser) -> Result<Self, Self::Error> {
41 let mut pairs = vec![];
42
43 loop {
44 match (parser.next_string(), parser.next_bytes()) {
45 (Ok(key), Ok(value)) => pairs.push((key, value)),
46 (Err(CommandParserError::EndOfStream), _) => {
50 break;
51 }
52 (_, Err(CommandParserError::EndOfStream)) => {
53 break;
54 }
55 (Err(err), _) => return Err(err.into()),
56 (_, Err(err)) => return Err(err.into()),
57 }
58 }
59
60 Ok(Self { pairs })
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::commands::Command;
68 use bytes::Bytes;
69
70 #[test]
71 fn insert_one() {
72 let store = Arc::new(Mutex::new(Store::new()));
73
74 let frame = Frame::Array(vec![
75 Frame::Bulk(Bytes::from("MSET")),
76 Frame::Bulk(Bytes::from("key1")),
77 Frame::Bulk(Bytes::from("value1")),
78 ]);
79 let cmd = Command::try_from(frame).unwrap();
80
81 assert_eq!(
82 cmd,
83 Command::Mset(Mset {
84 pairs: vec![(String::from("key1"), Bytes::from("value1"))]
85 })
86 );
87
88 let res = cmd.exec(store.clone()).unwrap();
89
90 assert_eq!(res, Frame::Simple("OK".to_string()));
91
92 assert_eq!(
93 store.lock().unwrap().get("key1").unwrap(),
94 &Bytes::from("value1")
95 );
96 }
97
98 #[test]
99 fn insert_many() {
100 let store = Arc::new(Mutex::new(Store::new()));
101
102 let frame = Frame::Array(vec![
103 Frame::Bulk(Bytes::from("MSET")),
104 Frame::Bulk(Bytes::from("key1")),
105 Frame::Bulk(Bytes::from("value1")),
106 Frame::Bulk(Bytes::from("key2")),
107 Frame::Bulk(Bytes::from("value2")),
108 Frame::Bulk(Bytes::from("key3")),
109 Frame::Bulk(Bytes::from("value3")),
110 ]);
111 let cmd = Command::try_from(frame).unwrap();
112
113 assert_eq!(
114 cmd,
115 Command::Mset(Mset {
116 pairs: vec![
117 (String::from("key1"), Bytes::from("value1")),
118 (String::from("key2"), Bytes::from("value2")),
119 (String::from("key3"), Bytes::from("value3"))
120 ]
121 })
122 );
123
124 let res = cmd.exec(store.clone()).unwrap();
125
126 assert_eq!(res, Frame::Simple("OK".to_string()));
127
128 assert_eq!(
129 store.lock().unwrap().get("key1"),
130 Some(&Bytes::from("value1")),
131 );
132
133 assert_eq!(
134 store.lock().unwrap().get("key2"),
135 Some(&Bytes::from("value2")),
136 );
137
138 assert_eq!(
139 store.lock().unwrap().get("key3"),
140 Some(&Bytes::from("value3")),
141 );
142 }
143
144 #[test]
145 fn overide_existing() {
146 let store = Arc::new(Mutex::new(Store::new()));
147
148 let frame = Frame::Array(vec![
149 Frame::Bulk(Bytes::from("MSET")),
150 Frame::Bulk(Bytes::from("key1")),
151 Frame::Bulk(Bytes::from("value1")),
152 ]);
153 let cmd = Command::try_from(frame).unwrap();
154
155 assert_eq!(
156 cmd,
157 Command::Mset(Mset {
158 pairs: vec![(String::from("key1"), Bytes::from("value1")),]
159 })
160 );
161
162 {
163 let mut store = store.lock().unwrap();
164 store.set(String::from("key1"), Bytes::from("1"));
165 }
166
167 let res = cmd.exec(store.clone()).unwrap();
168
169 assert_eq!(res, Frame::Simple("OK".to_string()));
170
171 assert_eq!(
172 store.lock().unwrap().get("key1").unwrap(),
173 &Bytes::from("value1")
174 );
175 }
176
177 #[test]
178 fn no_keys() {
179 let store = Arc::new(Mutex::new(Store::new()));
180
181 let frame = Frame::Array(vec![Frame::Bulk(Bytes::from("MSET"))]);
182 let cmd = Command::try_from(frame).unwrap();
183
184 assert_eq!(cmd, Command::Mset(Mset { pairs: vec![] }));
185
186 let res = cmd.exec(store.clone()).unwrap();
187
188 assert_eq!(
189 res,
190 Frame::Error("ERR wrong number of arguments for command".to_string())
191 );
192 }
193}