resp_protocol/array/
mod.rs

1use 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    /// Builad a new Array Builder
154    ///
155    /// # Example
156    /// ``` rust
157    /// use resp_protocol::{Array, ArrayBuilder};
158    ///
159    /// let array_builder: ArrayBuilder = ArrayBuilder::new();
160    /// let array: Array = array_builder.build();
161    /// ```
162    #[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    /// Add a new value to Array Builder
175    ///
176    /// # Example
177    /// ```rust
178    /// use resp_protocol::{RespType, Array, ArrayBuilder, SimpleString};
179    ///
180    /// let mut array_builder: ArrayBuilder = ArrayBuilder::new();
181    ///
182    /// let simple_string: SimpleString = SimpleString::new(b"OK");
183    ///
184    /// array_builder.insert(RespType::SimpleString(simple_string));
185    ///
186    /// let array: Array = array_builder.build();
187    /// ```
188    #[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); // "*"
207        bytes.put_slice(length_string.as_bytes());
208        bytes.put_u8(0x0d); // CR
209        bytes.put_u8(0x0a); // LF
210        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}