Skip to main content

tailtalk_packets/
aep.rs

1use thiserror::Error;
2
3const REQUEST: u8 = 1;
4const REPLY: u8 = 2;
5
6#[derive(Error, Debug)]
7pub enum AepError {
8    #[error("unknown AEP function code {code:?}")]
9    UnknownFunction { code: u8 },
10    #[error("invalid size - expected at least {expected:?} byte(s), but found {found:?}")]
11    InvalidSize { found: usize, expected: usize },
12}
13
14#[repr(u8)]
15#[derive(Debug, Copy, Clone, PartialEq, Eq)]
16pub enum AepFunction {
17    Request = REQUEST,
18    Reply = REPLY,
19}
20
21impl TryFrom<u8> for AepFunction {
22    type Error = AepError;
23
24    fn try_from(data: u8) -> Result<Self, Self::Error> {
25        match data {
26            REQUEST => Ok(Self::Request),
27            REPLY => Ok(Self::Reply),
28            _ => Err(AepError::UnknownFunction { code: data }),
29        }
30    }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct AepPacket {
35    pub function: AepFunction,
36}
37
38impl AepPacket {
39    pub fn parse(data: &[u8]) -> Result<Self, AepError> {
40        if data.is_empty() {
41            return Err(AepError::InvalidSize {
42                found: 0,
43                expected: 1,
44            });
45        }
46        let code = AepFunction::try_from(data[0])?;
47
48        Ok(Self { function: code })
49    }
50
51    pub fn set_code(&mut self, code: AepFunction) {
52        self.function = code;
53    }
54
55    pub fn to_bytes(self, buf: &mut [u8]) -> Result<usize, AepError> {
56        if buf.is_empty() {
57            return Err(AepError::InvalidSize {
58                found: buf.len(),
59                expected: 1,
60            });
61        }
62
63        buf[0] = self.function as u8;
64
65        Ok(1)
66    }
67
68    pub const fn len(&self) -> usize {
69        1
70    }
71
72    pub const fn is_empty(&self) -> bool {
73        false
74    }
75}