1use crate::resp2::types::*;
6use crate::resp2::utils::{self as resp2_utils};
7use crate::types::{RedisProtocolError, CRLF};
8use crate::utils;
9use crate::alloc::string::ToString;
10use alloc::vec::Vec;
11use bytes::BytesMut;
12use cookie_factory::GenError;
13
14fn gen_simplestring<'a>(x: (&'a mut [u8], usize), data: &[u8]) -> Result<(&'a mut [u8], usize), GenError> {
15 encode_checks!(x, resp2_utils::simplestring_encode_len(data));
16
17 do_gen!(
18 x,
19 gen_be_u8!(FrameKind::SimpleString.to_byte()) >> gen_slice!(data) >> gen_slice!(CRLF.as_bytes())
20 )
21}
22
23fn gen_error<'a>(x: (&'a mut [u8], usize), data: &str) -> Result<(&'a mut [u8], usize), GenError> {
24 encode_checks!(x, resp2_utils::error_encode_len(data));
25
26 do_gen!(
27 x,
28 gen_be_u8!(FrameKind::Error.to_byte()) >> gen_slice!(data.as_bytes()) >> gen_slice!(CRLF.as_bytes())
29 )
30}
31
32fn gen_integer<'a>(x: (&'a mut [u8], usize), data: &i64) -> Result<(&'a mut [u8], usize), GenError> {
33 encode_checks!(x, resp2_utils::integer_encode_len(data));
34
35 do_gen!(
36 x,
37 gen_be_u8!(FrameKind::Integer.to_byte()) >> gen_slice!(data.to_string().as_bytes()) >> gen_slice!(CRLF.as_bytes())
38 )
39}
40
41fn gen_bulkstring<'a>(x: (&'a mut [u8], usize), data: &[u8]) -> Result<(&'a mut [u8], usize), GenError> {
42 encode_checks!(x, resp2_utils::bulkstring_encode_len(data));
43
44 do_gen!(
45 x,
46 gen_be_u8!(FrameKind::BulkString.to_byte())
47 >> gen_slice!(data.len().to_string().as_bytes())
48 >> gen_slice!(CRLF.as_bytes())
49 >> gen_slice!(data)
50 >> gen_slice!(CRLF.as_bytes())
51 )
52}
53
54fn gen_null(x: (&mut [u8], usize)) -> Result<(&mut [u8], usize), GenError> {
55 encode_checks!(x, NULL.as_bytes().len());
56
57 do_gen!(x, gen_slice!(NULL.as_bytes()))
58}
59
60fn gen_array<'a>(x: (&'a mut [u8], usize), data: &Vec<Frame>) -> Result<(&'a mut [u8], usize), GenError> {
61 encode_checks!(x, resp2_utils::array_encode_len(data)?);
62
63 let mut x = do_gen!(
64 x,
65 gen_be_u8!(FrameKind::Array.to_byte())
66 >> gen_slice!(data.len().to_string().as_bytes())
67 >> gen_slice!(CRLF.as_bytes())
68 )?;
69
70 for frame in data.iter() {
71 x = match frame {
72 Frame::SimpleString(ref s) => gen_simplestring(x, &s)?,
73 Frame::BulkString(ref b) => gen_bulkstring(x, &b)?,
74 Frame::Null => gen_null(x)?,
75 Frame::Error(ref s) => gen_error(x, s)?,
76 Frame::Array(ref frames) => gen_array(x, frames)?,
77 Frame::Integer(ref i) => gen_integer(x, i)?,
78 };
79 }
80
81 Ok(x)
83}
84
85fn attempt_encoding(buf: &mut [u8], offset: usize, frame: &Frame) -> Result<usize, GenError> {
86 match *frame {
87 Frame::BulkString(ref b) => gen_bulkstring((buf, offset), b).map(|(_, l)| l),
88 Frame::Null => gen_null((buf, offset)).map(|(_, l)| l),
89 Frame::Array(ref frames) => gen_array((buf, offset), frames).map(|(_, l)| l),
90 Frame::Error(ref s) => gen_error((buf, offset), s).map(|(_, l)| l),
91 Frame::SimpleString(ref s) => gen_simplestring((buf, offset), s).map(|(_, l)| l),
92 Frame::Integer(ref i) => gen_integer((buf, offset), i).map(|(_, l)| l),
93 }
94}
95
96pub fn encode(buf: &mut [u8], offset: usize, frame: &Frame) -> Result<usize, RedisProtocolError> {
100 attempt_encoding(buf, offset, frame).map_err(|e| e.into())
101}
102
103pub fn encode_bytes(buf: &mut BytesMut, frame: &Frame) -> Result<usize, RedisProtocolError> {
107 let offset = buf.len();
108
109 loop {
110 match attempt_encoding(buf, offset, frame) {
111 Ok(size) => return Ok(size),
112 Err(e) => match e {
113 GenError::BufferTooSmall(amt) => utils::zero_extend(buf, amt),
114 _ => return Err(e.into()),
115 },
116 }
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::utils::*;
124
125 const PADDING: &'static str = "foobar";
126
127 fn encode_and_verify_empty(input: &Frame, expected: &str) {
128 let mut buf = BytesMut::new();
129
130 let len = match encode_bytes(&mut buf, input) {
131 Ok(l) => l,
132 Err(e) => panic!("{:?}", e),
133 };
134
135 assert_eq!(buf, expected.as_bytes(), "empty buf contents match");
136 assert_eq!(len, expected.as_bytes().len(), "empty expected len is correct");
137 }
138
139 fn encode_and_verify_non_empty(input: &Frame, expected: &str) {
140 let mut buf = BytesMut::new();
141 buf.extend_from_slice(PADDING.as_bytes());
142
143 let len = match encode_bytes(&mut buf, input) {
144 Ok(l) => l,
145 Err(e) => panic!("{:?}", e),
146 };
147 let padded = vec![PADDING, expected].join("");
148
149 assert_eq!(buf, padded.as_bytes(), "padded buf contents match");
150 assert_eq!(len, padded.as_bytes().len(), "padded expected len is correct");
151 }
152
153 fn encode_raw_and_verify_empty(input: &Frame, expected: &str) {
154 let mut buf = Vec::from(&ZEROED_KB[0..expected.as_bytes().len()]);
155
156 let len = match encode(&mut buf, 0, input) {
157 Ok(l) => l,
158 Err(e) => panic!("{:?}", e),
159 };
160
161 assert_eq!(buf, expected.as_bytes(), "empty buf contents match");
162 assert_eq!(len, expected.as_bytes().len(), "empty expected len is correct");
163 }
164
165 #[test]
166 fn should_encode_llen_req_example() {
167 let expected = "*2\r\n$4\r\nLLEN\r\n$6\r\nmylist\r\n";
168 let input = Frame::Array(vec![
169 Frame::BulkString("LLEN".into()),
170 Frame::BulkString("mylist".into()),
171 ]);
172
173 encode_and_verify_empty(&input, expected);
174 encode_and_verify_non_empty(&input, expected);
175 }
176
177 #[test]
178 fn should_encode_incr_req_example() {
179 let expected = "*2\r\n$4\r\nINCR\r\n$5\r\nmykey\r\n";
180 let input = Frame::Array(vec![
181 Frame::BulkString("INCR".into()),
182 Frame::BulkString("mykey".into()),
183 ]);
184
185 encode_and_verify_empty(&input, expected);
186 encode_and_verify_non_empty(&input, expected);
187 }
188
189 #[test]
190 fn should_encode_bitcount_req_example() {
191 let expected = "*2\r\n$8\r\nBITCOUNT\r\n$5\r\nmykey\r\n";
192 let input = Frame::Array(vec![
193 Frame::BulkString("BITCOUNT".into()),
194 Frame::BulkString("mykey".into()),
195 ]);
196
197 encode_and_verify_empty(&input, expected);
198 encode_and_verify_non_empty(&input, expected);
199 }
200
201 #[test]
202 fn should_encode_array_bulk_string_test() {
203 let expected = "*3\r\n$5\r\nWATCH\r\n$6\r\nWIBBLE\r\n$9\r\nfooBARbaz\r\n";
204 let input = Frame::Array(vec![
205 Frame::BulkString("WATCH".into()),
206 Frame::BulkString("WIBBLE".into()),
207 Frame::BulkString("fooBARbaz".into()),
208 ]);
209
210 encode_and_verify_empty(&input, expected);
211 encode_and_verify_non_empty(&input, expected);
212 }
213
214 #[test]
215 fn should_encode_array_null_test() {
216 let expected = "*3\r\n$4\r\nHSET\r\n$3\r\nfoo\r\n$-1\r\n";
217 let input = Frame::Array(vec![
218 Frame::BulkString("HSET".into()),
219 Frame::BulkString("foo".into()),
220 Frame::Null,
221 ]);
222
223 encode_and_verify_empty(&input, expected);
224 encode_and_verify_non_empty(&input, expected);
225 }
226
227 #[test]
228 fn should_encode_raw_llen_req_example() {
229 let expected = "*2\r\n$4\r\nLLEN\r\n$6\r\nmylist\r\n";
230 let input = Frame::Array(vec![
231 Frame::BulkString("LLEN".into()),
232 Frame::BulkString("mylist".into()),
233 ]);
234
235 encode_raw_and_verify_empty(&input, expected);
236 }
237
238 #[test]
239 fn should_encode_raw_incr_req_example() {
240 let expected = "*2\r\n$4\r\nINCR\r\n$5\r\nmykey\r\n";
241 let input = Frame::Array(vec![
242 Frame::BulkString("INCR".into()),
243 Frame::BulkString("mykey".into()),
244 ]);
245
246 encode_raw_and_verify_empty(&input, expected);
247 }
248
249 #[test]
250 fn should_encode_raw_bitcount_req_example() {
251 let expected = "*2\r\n$8\r\nBITCOUNT\r\n$5\r\nmykey\r\n";
252 let input = Frame::Array(vec![
253 Frame::BulkString("BITCOUNT".into()),
254 Frame::BulkString("mykey".into()),
255 ]);
256
257 encode_raw_and_verify_empty(&input, expected);
258 }
259
260 #[test]
261 fn should_encode_raw_array_bulk_string_test() {
262 let expected = "*3\r\n$5\r\nWATCH\r\n$6\r\nWIBBLE\r\n$9\r\nfooBARbaz\r\n";
263 let input = Frame::Array(vec![
264 Frame::BulkString("WATCH".into()),
265 Frame::BulkString("WIBBLE".into()),
266 Frame::BulkString("fooBARbaz".into()),
267 ]);
268
269 encode_raw_and_verify_empty(&input, expected);
270 }
271
272 #[test]
273 fn should_encode_raw_array_null_test() {
274 let expected = "*3\r\n$4\r\nHSET\r\n$3\r\nfoo\r\n$-1\r\n";
275 let input = Frame::Array(vec![
276 Frame::BulkString("HSET".into()),
277 Frame::BulkString("foo".into()),
278 Frame::Null,
279 ]);
280
281 encode_raw_and_verify_empty(&input, expected);
282 }
283
284 #[test]
285 fn should_encode_moved_error() {
286 let expected = "-MOVED 3999 127.0.0.1:6381\r\n";
287 let input = Frame::Error("MOVED 3999 127.0.0.1:6381".into());
288
289 encode_and_verify_empty(&input, expected);
290 encode_and_verify_non_empty(&input, expected);
291 }
292
293 #[test]
294 fn should_encode_ask_error() {
295 let expected = "-ASK 3999 127.0.0.1:6381\r\n";
296 let input = Frame::Error("ASK 3999 127.0.0.1:6381".into());
297
298 encode_and_verify_empty(&input, expected);
299 encode_and_verify_non_empty(&input, expected);
300 }
301
302 #[test]
303 fn should_encode_error() {
304 let expected = "-WRONGTYPE Operation against a key holding the wrong kind of value\r\n";
305 let input = Frame::Error("WRONGTYPE Operation against a key holding the wrong kind of value".into());
306
307 encode_and_verify_empty(&input, expected);
308 encode_and_verify_non_empty(&input, expected);
309 }
310
311 #[test]
312 fn should_encode_simplestring() {
313 let expected = "+OK\r\n";
314 let input = Frame::SimpleString("OK".into());
315
316 encode_and_verify_empty(&input, expected);
317 encode_and_verify_non_empty(&input, expected);
318 }
319
320 #[test]
321 fn should_encode_integer() {
322 let i1_expected = ":1000\r\n";
323 let i1_input = Frame::Integer(1000);
324
325 encode_and_verify_empty(&i1_input, i1_expected);
326 encode_and_verify_non_empty(&i1_input, i1_expected);
327 }
328
329 #[test]
330 fn should_encode_negative_integer() {
331 let i2_expected = ":-1000\r\n";
332 let i2_input = Frame::Integer(-1000);
333
334 encode_and_verify_empty(&i2_input, i2_expected);
335 encode_and_verify_non_empty(&i2_input, i2_expected);
336 }
337}