resp_protocol/simple_string/
mod.rs

1use crate::RespError;
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4#[derive(Debug, Clone, PartialEq)]
5pub struct SimpleString(Bytes);
6
7/// Simple string type
8impl SimpleString {
9    /// Build a new Simple string
10    ///
11    /// # Example
12    /// ```
13    /// use resp_protocol::SimpleString;
14    ///
15    /// let simple_string = SimpleString::new(b"OK");
16    /// ```
17    #[inline]
18    pub fn new(value: &[u8]) -> Self {
19        let mut bytes = BytesMut::with_capacity(value.len() + 3);
20        bytes.put_u8(0x2b); // "+"
21        bytes.put_slice(value);
22        bytes.put_u8(0x0d); // CR
23        bytes.put_u8(0x0a); // LF
24        Self::from_bytes(bytes.freeze())
25    }
26
27    ///
28    ///
29    /// ``` rust
30    /// use resp_protocol::SimpleString;
31    /// use bytes::Bytes;
32    ///
33    /// let simple_string: SimpleString = SimpleString::new(b"OK");
34    /// let bytes: Bytes = simple_string.bytes();
35    /// println!("{:?}", bytes); // b"+OK\r\n"
36    /// ```
37    #[inline]
38    pub fn bytes(&self) -> Bytes {
39        self.0.clone()
40    }
41
42    ///
43    ///
44    /// ``` rust
45    /// use resp_protocol::SimpleString;
46    ///
47    /// let simple_string: SimpleString = SimpleString::new(b"OK");
48    /// let length: usize = simple_string.len();
49    /// println!("{:?}", length); // 5
50    /// ```
51    #[inline]
52    pub fn len(&self) -> usize {
53        self.0.len()
54    }
55
56    ///
57    ///
58    /// ``` rust
59    /// use resp_protocol::SimpleString;
60    ///
61    /// let simple_string: SimpleString = SimpleString::new(b"OK");
62    /// let value: Vec<u8> = simple_string.value();
63    /// println!("{:?}", value); // [79, 75]
64    /// ```
65    #[inline]
66    pub fn value(&self) -> Vec<u8> {
67        let length = self.len();
68        let mut bytes = self.bytes().slice(1..(length - 2));
69        let mut vector = Vec::<u8>::with_capacity(length - 3);
70        unsafe {
71            vector.set_len(length - 3);
72        }
73        bytes.copy_to_slice(vector.as_mut_slice());
74        vector
75    }
76
77    ///
78    ///
79    /// ``` rust
80    /// use resp_protocol::SimpleString;
81    ///
82    /// let simple_string: SimpleString = SimpleString::new(b"OK");
83    /// let value_length: usize = simple_string.value_len();
84    /// println!("{:?}", value_length); // 2
85    /// ```
86    #[inline]
87    pub fn value_len(&self) -> usize {
88        self.len() - 3
89    }
90
91    pub fn validate_value(input: &[u8]) -> Result<(), RespError> {
92        let mut index = 0;
93        let length = input.len();
94        while index < length && input[index] != 0x0d && input[index] != 0x0a {
95            index += 1;
96        }
97        if index != length {
98            return Err(RespError::InvalidValue);
99        }
100        Ok(())
101    }
102
103    #[inline]
104    pub fn from_bytes(input: Bytes) -> Self {
105        Self(input)
106    }
107
108    #[inline]
109    pub fn from_slice(input: &[u8]) -> Self {
110        let bytes = Bytes::copy_from_slice(input);
111        Self::from_bytes(bytes)
112    }
113
114    /// Build as new Simple String from raw pointer
115    ///
116    /// # Example
117    /// ```
118    /// use resp_protocol::SimpleString;
119    /// use std::mem::ManuallyDrop;
120    ///
121    /// let string: String = "+OK\r\n".to_owned();
122    /// let mut mdrop_string: ManuallyDrop<String> = ManuallyDrop::new(string);
123    /// let simple_string: SimpleString = unsafe { SimpleString::from_raw(mdrop_string.as_mut_ptr(), mdrop_string.len()) };
124    /// ```
125    #[inline]
126    pub unsafe fn from_raw(ptr: *mut u8, length: usize) -> Self {
127        let vector = Vec::from_raw_parts(ptr, length, length);
128        let bytes = Bytes::from(vector);
129        Self::from_bytes(bytes)
130    }
131
132    pub fn while_valid(input: &[u8], start: &mut usize, end: &usize) -> Result<(), RespError> {
133        let mut index = *start;
134        if index >= *end || input[index] != 0x2b {
135            return Err(RespError::InvalidFirstChar);
136        }
137        index += 1;
138        while index < *end && input[index] != 0x0d && input[index] != 0x0a {
139            index += 1;
140        }
141        if index + 1 >= *end || input[index] != 0x0d || input[index + 1] != 0x0a {
142            return Err(RespError::InvalidTerminate);
143        };
144        *start = index + 2;
145        Ok(())
146    }
147
148    pub fn parse(input: &[u8], start: &mut usize, end: &usize) -> Result<Self, RespError> {
149        let mut index = *start;
150        Self::while_valid(input, &mut index, end)?;
151        let value = Self::from_slice(&input[*start..index]);
152        *start = index;
153        Ok(value)
154    }
155}
156
157#[cfg(test)]
158mod tests_simple_string {
159    use crate::simple_string::SimpleString;
160    use bytes::Bytes;
161
162    #[test]
163    fn test_new() {
164        let string = "OK";
165        let simple_string = SimpleString::new(string.as_bytes());
166        assert_eq!(simple_string, SimpleString(Bytes::from_static(b"+OK\r\n")));
167    }
168
169    #[test]
170    fn test_value() {
171        let simple_string = SimpleString(Bytes::from_static(b"+OK\r\n"));
172        assert_eq!(simple_string.value(), Vec::from("OK"));
173        assert_eq!(simple_string.value(), Vec::from("OK"));
174    }
175
176    #[test]
177    fn test_value_len() {
178        let simple_string = SimpleString(Bytes::from_static(b"+OK\r\n"));
179        assert_eq!(simple_string.value_len(), 2);
180        assert_eq!(simple_string.value_len(), 2);
181    }
182
183    #[test]
184    fn test_bytes() {
185        let simple_string = SimpleString(Bytes::from_static(b"+OK\r\n"));
186        assert_eq!(simple_string.bytes(), Bytes::from_static(b"+OK\r\n"));
187        assert_eq!(simple_string.bytes(), Bytes::from_static(b"+OK\r\n"));
188    }
189
190    #[test]
191    fn test_len() {
192        let simple_string = SimpleString(Bytes::from_static(b"+OK\r\n"));
193        assert_eq!(simple_string.len(), 5);
194        assert_eq!(simple_string.len(), 5);
195    }
196
197    #[test]
198    fn test_validate_valid_value() {
199        let value = b"OK";
200        assert_eq!(SimpleString::validate_value(value).unwrap(), ())
201    }
202
203    #[test]
204    #[should_panic(expected = "InvalidValue")]
205    fn test_validate_invalid_value() {
206        let value = b"O\r\nK";
207        assert_eq!(SimpleString::validate_value(value).unwrap(), ())
208    }
209
210    #[test]
211    fn test_parse() {
212        let string = "+foo\r\n+bar\r\n";
213        let mut cursor = 0;
214        let end = string.len();
215        assert_eq!(
216            SimpleString::parse(string.as_bytes(), &mut cursor, &end).unwrap(),
217            SimpleString::new("foo".as_bytes())
218        );
219        assert_eq!(cursor, 6);
220    }
221}