resp_protocol/array/
mod.rs1use crate::{BulkString, Error, Integer, RespError, RespType, SimpleString};
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4pub const EMPTY_ARRAY: Array = Array(Bytes::from_static(b"*0\r\n"));
5pub const NULL_ARRAY: Array = Array(Bytes::from_static(b"*-1\r\n"));
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct Array(Bytes);
9
10impl Array {
11 #[inline]
12 pub fn len(&self) -> usize {
13 self.0.len()
14 }
15
16 #[inline]
17 pub fn bytes(&self) -> Bytes {
18 self.0.clone()
19 }
20
21 #[inline]
22 pub fn to_vec(&self) -> Vec<u8> {
23 let length = self.0.len();
24 let mut vector = Vec::<u8>::with_capacity(length);
25 unsafe {
26 vector.set_len(length - 3);
27 }
28 self.bytes().copy_to_slice(vector.as_mut_slice());
29 vector
30 }
31
32 #[inline]
33 pub fn is_empty(&self) -> bool {
34 self == EMPTY_ARRAY
35 }
36
37 #[inline]
38 pub fn is_null(&self) -> bool {
39 self == NULL_ARRAY
40 }
41
42 #[inline]
43 pub fn from_bytes(input: Bytes) -> Self {
44 Self(input)
45 }
46
47 #[inline]
48 pub fn from_slice(input: &[u8]) -> Self {
49 let bytes = Bytes::copy_from_slice(input);
50 Self::from_bytes(bytes)
51 }
52
53 #[inline]
54 pub unsafe fn from_raw(ptr: *mut u8, length: usize) -> Self {
55 let vector = Vec::from_raw_parts(ptr, length, length);
56 let bytes = Bytes::from(vector);
57 Self::from_bytes(bytes)
58 }
59
60 pub fn while_valid(input: &[u8], start: &mut usize, end: &usize) -> Result<(), RespError> {
61 let mut index = *start;
62 if index + 3 >= *end {
63 return Err(RespError::InvalidValue);
64 }
65 if input[index] != 0x2a {
66 return Err(RespError::InvalidFirstChar);
67 }
68 index += 1;
69 if input[index] == 0x2d {
70 if input[index + 1] != 0x31
71 || input[index + 2] != 0x0d
72 || index + 3 == *end
73 || input[index + 3] != 0x0a
74 {
75 return Err(RespError::InvalidNullValue);
76 }
77 *start = index + 4;
78 return Ok(());
79 }
80 if input[index] == 0x30 && input[index + 1] >= 0x30 && input[index + 1] <= 0x39 {
81 return Err(RespError::InvalidLength);
82 }
83 while index < *end && input[index] >= 0x30 && input[index] <= 0x39 {
84 index += 1;
85 }
86 if index + 1 >= *end || input[index] != 0x0d || input[index + 1] != 0x0a {
87 return Err(RespError::InvalidLengthSeparator);
88 }
89 let length = unsafe {
90 String::from_utf8_unchecked(input[*start + 1..index].to_vec())
91 .parse::<usize>()
92 .unwrap()
93 };
94 index += 2;
95 if length == 0 {
96 *start = index;
97 return Ok(());
98 }
99 if index >= *end {
100 return Err(RespError::InvalidValue);
101 }
102 let mut count = 0;
103 while count < length {
104 match input[index] {
105 0x2b => {
106 SimpleString::while_valid(input, &mut index, end)?;
107 }
108 0x2d => {
109 Error::while_valid(input, &mut index, end)?;
110 }
111 0x3a => {
112 Integer::while_valid(input, &mut index, end)?;
113 }
114 0x24 => {
115 BulkString::while_valid(input, &mut index, end)?;
116 }
117 0x2a => {
118 Self::while_valid(input, &mut index, end)?;
119 }
120 _ => {
121 return Err(RespError::InvalidValue);
122 }
123 }
124 count += 1;
125 }
126 *start = index;
127 Ok(())
128 }
129
130 pub fn parse(input: &[u8], start: &mut usize, end: &usize) -> Result<Self, RespError> {
131 let mut index = *start;
132 Self::while_valid(input, &mut index, end)?;
133 let value = Self::from_slice(&input[*start..index]);
134 *start = index;
135 Ok(value)
136 }
137}
138
139impl<'a> PartialEq<Array> for &'a Array {
140 fn eq(&self, other: &Array) -> bool {
141 self.0 == other.bytes()
142 }
143 fn ne(&self, other: &Array) -> bool {
144 self.0 != other.bytes()
145 }
146}
147
148pub struct ArrayBuilder {
149 inner: Vec<RespType>,
150}
151
152impl ArrayBuilder {
153 #[inline]
163 pub fn new() -> ArrayBuilder {
164 ArrayBuilder {
165 inner: Vec::<RespType>::new(),
166 }
167 }
168
169 #[inline]
170 pub fn value(&mut self) -> Vec<RespType> {
171 self.inner.clone()
172 }
173
174 #[inline]
189 pub fn insert(&mut self, value: RespType) -> &mut Self {
190 self.inner.push(value);
191 self
192 }
193
194 #[inline]
195 pub fn build(&self) -> Array {
196 let length = self.inner.len();
197 if length == 0 {
198 return EMPTY_ARRAY;
199 }
200 let length_string = length.to_string();
201 let mut total_bytes = length_string.len() + 3;
202 for element in &self.inner {
203 total_bytes += element.len();
204 }
205 let mut bytes = BytesMut::with_capacity(total_bytes);
206 bytes.put_u8(0x2a); bytes.put_slice(length_string.as_bytes());
208 bytes.put_u8(0x0d); bytes.put_u8(0x0a); for element in &self.inner {
211 bytes.put(element.bytes());
212 }
213 Array(bytes.freeze())
214 }
215}
216
217#[cfg(test)]
218mod tests_array {
219 use crate::{
220 Array, ArrayBuilder, BulkString, Integer, RespType, SimpleString, EMPTY_ARRAY, NULL_ARRAY,
221 };
222 use bytes::Bytes;
223
224 #[test]
225 fn test_build_empty_array() {
226 let array_builder = ArrayBuilder::new();
227 assert_eq!(array_builder.build(), EMPTY_ARRAY)
228 }
229
230 #[test]
231 fn test_build_array() {
232 let mut array_builder = ArrayBuilder::new();
233 array_builder.insert(RespType::SimpleString(SimpleString::new(b"foo")));
234 assert_eq!(
235 array_builder.build().bytes(),
236 Bytes::from_static(b"*1\r\n+foo\r\n")
237 );
238 array_builder.insert(RespType::BulkString(BulkString::new(b"bar")));
239 assert_eq!(
240 array_builder.build().bytes(),
241 Bytes::from_static(b"*2\r\n+foo\r\n$3\r\nbar\r\n")
242 );
243 array_builder.insert(RespType::Integer(Integer::new(-100)));
244 assert_eq!(
245 array_builder.build().bytes(),
246 Bytes::from_static(b"*3\r\n+foo\r\n$3\r\nbar\r\n:-100\r\n")
247 );
248 let mut subarray_builder = ArrayBuilder::new();
249 subarray_builder.insert(RespType::SimpleString(SimpleString::new(b"foo")));
250 subarray_builder.insert(RespType::SimpleString(SimpleString::new(b"bar")));
251 let subarray = subarray_builder.build();
252 assert_eq!(
253 subarray.bytes(),
254 Bytes::from_static(b"*2\r\n+foo\r\n+bar\r\n")
255 );
256 array_builder.insert(RespType::Array(subarray));
257 assert_eq!(
258 array_builder.build().bytes(),
259 Bytes::from_static(b"*4\r\n+foo\r\n$3\r\nbar\r\n:-100\r\n*2\r\n+foo\r\n+bar\r\n")
260 );
261 }
262
263 #[test]
264 fn test_parse_empty() {
265 let string = "*0\r\n";
266 let mut cursor = 0;
267 let array = Array::parse(string.as_bytes(), &mut cursor, &string.len()).unwrap();
268
269 assert_eq!(array, EMPTY_ARRAY);
270 assert_eq!(cursor, 4);
271 }
272
273 #[test]
274 fn test_parse_null() {
275 let string = "*-1\r\n";
276 let mut cursor = 0;
277 let array = Array::parse(string.as_bytes(), &mut cursor, &string.len()).unwrap();
278
279 assert_eq!(array, NULL_ARRAY);
280 assert_eq!(cursor, 5);
281 }
282
283 #[test]
284 fn parse_array_with_integers() {
285 let string = "*3\r\n:1\r\n:2\r\n:3\r\n";
286 let mut cursor = 0;
287 let array = Array::parse(string.as_bytes(), &mut cursor, &string.len()).unwrap();
288
289 let referance_array = ArrayBuilder::new()
290 .insert(RespType::Integer(Integer::new(1)))
291 .insert(RespType::Integer(Integer::new(2)))
292 .insert(RespType::Integer(Integer::new(3)))
293 .build();
294
295 assert_eq!(array, referance_array);
296 assert_eq!(cursor, 16);
297 }
298
299 #[test]
300 fn parse_array_with_bulk_strings() {
301 let string = "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n";
302 let mut cursor = 0;
303 let array = Array::parse(string.as_bytes(), &mut cursor, &string.len()).unwrap();
304
305 let referance_array = ArrayBuilder::new()
306 .insert(RespType::BulkString(BulkString::new(b"foo")))
307 .insert(RespType::BulkString(BulkString::new(b"bar")))
308 .build();
309
310 assert_eq!(array, referance_array);
311 assert_eq!(cursor, 22);
312 }
313}