slip_codec/
encoder.rs

1use crate::{END, ESC, ESC_END, ESC_ESC};
2
3/// SLIP encoder context
4#[derive(Debug)]
5pub struct SlipEncoder {
6    begin_with_end: bool,
7}
8
9impl SlipEncoder {
10    /// Creates a new encoder context
11    pub fn new(begin_with_end: bool) -> Self {
12        Self { begin_with_end }
13    }
14
15    /// Encodes the given buffer in a SLIP frame and forwards it to the sink.
16    ///
17    /// # Arguments
18    ///
19    /// * `buf` - input data buffer for encoding
20    /// * `sink` - output object implementing the std::io::Write trait
21    ///
22    /// Returns the number of bytes written to the sink.
23    ///
24    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}