1use crate::{END, ESC, ESC_END, ESC_ESC};
2
3#[derive(Debug)]
5pub struct SlipEncoder {
6 begin_with_end: bool,
7}
8
9impl SlipEncoder {
10 pub fn new(begin_with_end: bool) -> Self {
12 Self { begin_with_end }
13 }
14
15 pub fn encode(&mut self, buf: &[u8], sink: &mut dyn std::io::Write) -> std::io::Result<usize> {
25 let mut len = if self.begin_with_end {
26 sink.write(&[END])?
27 } else {
28 0
29 };
30
31 for value in buf.iter() {
32 match *value {
33 END => {
34 len += sink.write(&[ESC, ESC_END])?;
35 }
36 ESC => {
37 len += sink.write(&[ESC, ESC_ESC])?;
38 }
39 _ => {
40 len += sink.write(&[*value])?;
41 }
42 }
43 }
44
45 len += sink.write(&[END])?;
46
47 sink.flush()?;
48
49 Ok(len)
50 }
51}
52
53impl Default for SlipEncoder {
54 fn default() -> Self {
55 Self::new(true)
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn empty_encode() {
65 const EXPECTED: [u8; 2] = [0xc0, 0xc0];
66 let mut output = Vec::<u8>::new();
67
68 let mut slip = SlipEncoder::new(true);
69 let len = slip.encode(&[0; 0], &mut output).unwrap();
70 assert_eq!(EXPECTED.len(), len);
71 assert_eq!(&EXPECTED, output.as_slice());
72 }
73
74 #[test]
75 fn encode_esc_esc_sequence() {
76 const INPUT: [u8; 3] = [0x01, ESC, 0x03];
77 const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_ESC, 0x03, 0xc0];
78 let mut output = Vec::<u8>::new();
79
80 let mut slip = SlipEncoder::new(true);
81 let len = slip.encode(&INPUT, &mut output).unwrap();
82 assert_eq!(EXPECTED.len(), len);
83 assert_eq!(&EXPECTED, output.as_slice());
84 }
85
86 #[test]
87 fn encode_end_esc_sequence() {
88 const INPUT: [u8; 3] = [0x01, END, 0x03];
89 const EXPECTED: [u8; 6] = [0xc0, 0x01, ESC, ESC_END, 0x03, 0xc0];
90 let mut output = Vec::<u8>::new();
91
92 let mut slip = SlipEncoder::new(true);
93 let len = slip.encode(&INPUT, &mut output).unwrap();
94 assert_eq!(EXPECTED.len(), len);
95 assert_eq!(&EXPECTED, output.as_slice());
96 }
97}