resp_protocol/simple_string/
mod.rs1use crate::RespError;
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4#[derive(Debug, Clone, PartialEq)]
5pub struct SimpleString(Bytes);
6
7impl SimpleString {
9 #[inline]
18 pub fn new(value: &[u8]) -> Self {
19 let mut bytes = BytesMut::with_capacity(value.len() + 3);
20 bytes.put_u8(0x2b); bytes.put_slice(value);
22 bytes.put_u8(0x0d); bytes.put_u8(0x0a); Self::from_bytes(bytes.freeze())
25 }
26
27 #[inline]
38 pub fn bytes(&self) -> Bytes {
39 self.0.clone()
40 }
41
42 #[inline]
52 pub fn len(&self) -> usize {
53 self.0.len()
54 }
55
56 #[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 #[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 #[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}