1use core::ops::Deref;
2
3use noalloc_vec_rs::vec::Vec;
4
5pub const END_CHAR: u8 = 0xC0;
6pub const ESC_CHAR: u8 = 0xDB;
7pub const ESC_END_CHAR: u8 = 0xDC;
8pub const ESC_ESC_CHAR: u8 = 0xDD;
9
10pub struct SlipEncoder;
14
15impl SlipEncoder {
16 #[allow(clippy::result_unit_err)]
28 pub fn encode<const MAX_LENGTH: usize>(vec: &mut Vec<u8, MAX_LENGTH>) -> Result<(), ()> {
29 vec.insert(0, END_CHAR)?;
31
32 let mut index = 1;
33 while index < vec.len() {
34 match vec[index] {
35 END_CHAR => {
36 vec.insert(index, ESC_CHAR)?;
37 vec.write(index + 1, ESC_END_CHAR)?;
38 index += 2;
39 }
40 ESC_CHAR => {
41 vec.insert(index, ESC_CHAR)?;
42 vec.write(index + 1, ESC_ESC_CHAR)?;
43 index += 2;
44 }
45 _ => {
46 index += 1;
47 }
48 }
49 }
50
51 vec.insert(vec.len(), END_CHAR)?;
53
54 Ok(())
55 }
56}
57
58#[derive(Debug, Default, PartialEq)]
60enum SlipDecoderState {
61 #[default]
63 Start,
64 End,
66 Append,
68 Escape,
70}
71
72#[derive(Default)]
76pub struct SlipDecoder<const MAX_LENGTH: usize> {
77 state: SlipDecoderState,
79 buffer: Vec<u8, MAX_LENGTH>,
81}
82
83impl<const MAX_LENGTH: usize> SlipDecoder<MAX_LENGTH> {
84 #[allow(clippy::result_unit_err)]
95 pub fn insert(&mut self, value: u8) -> Result<(), ()> {
96 match self.state {
97 SlipDecoderState::Start => {
98 if value == END_CHAR {
99 self.state = SlipDecoderState::Append;
100 }
101
102 Ok(())
103 }
104 SlipDecoderState::Append => {
105 match value {
106 END_CHAR => {
107 self.state = SlipDecoderState::End;
108 }
109 ESC_CHAR => {
110 self.state = SlipDecoderState::Escape;
111 }
112 _ => {
113 self.buffer.push(value)?;
114 }
115 }
116
117 Ok(())
118 }
119 SlipDecoderState::Escape => {
120 self.state = SlipDecoderState::Append;
121
122 match value {
123 ESC_END_CHAR => {
124 self.buffer.push(END_CHAR)?;
125
126 Ok(())
127 }
128 ESC_ESC_CHAR => {
129 self.buffer.push(ESC_CHAR)?;
130
131 Ok(())
132 }
133 _ => Err(()),
134 }
135 }
136 SlipDecoderState::End => Err(()),
137 }
138 }
139
140 pub fn reset(&mut self) {
142 self.state = SlipDecoderState::Start;
143 self.buffer.clear();
144 }
145
146 #[must_use]
153 pub fn is_buffer_completed(&self) -> bool {
154 self.state == SlipDecoderState::End
155 }
156
157 #[must_use]
163 pub const fn get_buffer(&self) -> &[u8] {
164 self.buffer.as_slice()
165 }
166}
167
168impl<const MAX_LENGTH: usize> Deref for SlipDecoder<MAX_LENGTH> {
170 type Target = [u8];
171
172 fn deref(&self) -> &Self::Target {
173 self.get_buffer()
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::slip::END_CHAR;
180 use crate::slip::ESC_CHAR;
181 use crate::slip::ESC_END_CHAR;
182 use crate::slip::ESC_ESC_CHAR;
183 use crate::slip::SlipDecoder;
184 use crate::slip::SlipDecoderState;
185 use crate::slip::SlipEncoder;
186 use noalloc_vec_rs::vec::Vec;
187
188 #[test]
189 fn test_encode() {
190 let mut array = Vec::<u8, 12>::from([0x00, 0x01, 0x02, 0x03]);
191
192 let result = SlipEncoder::encode(&mut array);
193
194 assert!(result.is_ok());
195 assert_eq!(*array, [END_CHAR, 0x00, 0x01, 0x02, 0x03, END_CHAR]);
196 }
197
198 #[test]
199 fn test_encode_empty() {
200 let mut array = Vec::<u8, 12>::new();
201
202 let result = SlipEncoder::encode(&mut array);
203
204 assert!(result.is_ok());
205 assert_eq!(*array, [END_CHAR, END_CHAR]);
206 }
207
208 #[test]
209 fn test_encode_with_escape_characters() {
210 let mut array = Vec::<u8, 12>::from([END_CHAR, ESC_CHAR, ESC_END_CHAR, ESC_ESC_CHAR]);
211
212 let result = SlipEncoder::encode(&mut array);
213
214 assert!(result.is_ok());
215 assert_eq!(
216 *array,
217 [
218 END_CHAR,
219 ESC_CHAR,
220 ESC_END_CHAR,
221 ESC_CHAR,
222 ESC_ESC_CHAR,
223 ESC_END_CHAR,
224 ESC_ESC_CHAR,
225 END_CHAR
226 ]
227 );
228 }
229
230 #[test]
231 fn test_decode() {
232 let mut slip_decoder = SlipDecoder::<1>::default();
233
234 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
235
236 let result = slip_decoder.insert(END_CHAR);
237 assert!(result.is_ok());
238 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
239
240 let result = slip_decoder.insert(0x00);
241 assert!(result.is_ok());
242 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
243
244 let result = slip_decoder.insert(END_CHAR);
245 assert!(result.is_ok());
246 assert_eq!(slip_decoder.state, SlipDecoderState::End);
247
248 assert!(slip_decoder.is_buffer_completed());
249
250 assert_eq!(slip_decoder.get_buffer(), &[0x00]);
251 }
252
253 #[test]
254 fn test_decode_with_escape_characters() {
255 let mut slip_decoder = SlipDecoder::<6>::default();
256
257 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
258
259 let result = slip_decoder.insert(END_CHAR);
260 assert!(result.is_ok());
261 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
262
263 let result = slip_decoder.insert(ESC_CHAR);
264 assert!(result.is_ok());
265 assert_eq!(slip_decoder.state, SlipDecoderState::Escape);
266
267 let result = slip_decoder.insert(ESC_END_CHAR);
268 assert!(result.is_ok());
269 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
270
271 let result = slip_decoder.insert(ESC_CHAR);
272 assert!(result.is_ok());
273 assert_eq!(slip_decoder.state, SlipDecoderState::Escape);
274
275 let result = slip_decoder.insert(ESC_ESC_CHAR);
276 assert!(result.is_ok());
277 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
278
279 let result = slip_decoder.insert(END_CHAR);
280 assert!(result.is_ok());
281 assert_eq!(slip_decoder.state, SlipDecoderState::End);
282
283 assert!(slip_decoder.is_buffer_completed());
284
285 assert_eq!(slip_decoder.get_buffer(), &[END_CHAR, ESC_CHAR]);
286 }
287
288 #[test]
289 fn test_decode_with_bad_escape_character() {
290 let mut slip_decoder = SlipDecoder::<1>::default();
291
292 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
293
294 let result = slip_decoder.insert(END_CHAR);
295 assert!(result.is_ok());
296 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
297
298 let result = slip_decoder.insert(ESC_CHAR);
299 assert!(result.is_ok());
300 assert_eq!(slip_decoder.state, SlipDecoderState::Escape);
301
302 let result = slip_decoder.insert(0x00);
303 assert!(result.is_err());
304 }
305
306 #[test]
307 fn test_decode_empty() {
308 let mut slip_decoder = SlipDecoder::<0>::default();
309
310 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
311
312 let result = slip_decoder.insert(END_CHAR);
313 assert!(result.is_ok());
314 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
315
316 let result = slip_decoder.insert(END_CHAR);
317 assert!(result.is_ok());
318 assert_eq!(slip_decoder.state, SlipDecoderState::End);
319
320 assert!(slip_decoder.is_buffer_completed());
321
322 assert_eq!(slip_decoder.get_buffer(), &[]);
323 }
324
325 #[test]
326 fn test_decode_and_reset() {
327 let mut slip_decoder = SlipDecoder::<1>::default();
328
329 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
330
331 let result = slip_decoder.insert(END_CHAR);
332 assert!(result.is_ok());
333 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
334
335 let result = slip_decoder.insert(0x00);
336 assert!(result.is_ok());
337 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
338
339 let result = slip_decoder.insert(END_CHAR);
340 assert!(result.is_ok());
341 assert_eq!(slip_decoder.state, SlipDecoderState::End);
342
343 assert!(slip_decoder.is_buffer_completed());
344
345 assert_eq!(slip_decoder.get_buffer(), &[0x00]);
346
347 slip_decoder.reset();
348 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
349 assert!(!slip_decoder.is_buffer_completed());
350 }
351
352 #[test]
353 fn test_decode_with_not_enough_space() {
354 let mut slip_decoder = SlipDecoder::<1>::default();
355
356 assert_eq!(slip_decoder.state, SlipDecoderState::Start);
357
358 let result = slip_decoder.insert(END_CHAR);
359 assert!(result.is_ok());
360 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
361
362 let result = slip_decoder.insert(0x00);
363 assert!(result.is_ok());
364 assert_eq!(slip_decoder.state, SlipDecoderState::Append);
365
366 let result = slip_decoder.insert(0x00);
367 assert!(result.is_err());
368 }
369}