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