omnitiles/protocol/
parser.rs1use crate::protocol::messages::*;
10
11enum State {
12 WaitStart,
13 WaitId,
14 WaitPayload { id: u8 },
15 WaitChecksum { id: u8, payload: Option<u8> },
16}
17
18pub struct Parser {
19 state: State,
20 checksum: u8,
21}
22
23impl Parser {
24 pub fn new() -> Self {
25 Self {
26 state: State::WaitStart,
27 checksum: 0,
28 }
29 }
30
31 pub fn push(&mut self, byte: u8) -> Option<Command> {
33 match self.state {
34 State::WaitStart => {
35 if byte == START_BYTE {
36 self.state = State::WaitId;
37 self.checksum = 0;
38 }
39 }
40 State::WaitId => {
41 self.checksum = self.checksum.wrapping_add(byte);
42
43 match byte {
44 MSG_M1_EXTEND | MSG_M1_RETRACT | MSG_M1_SET_POSITION | MSG_M2_EXTEND
46 | MSG_M2_RETRACT | MSG_M2_SET_POSITION => {
47 self.state = State::WaitPayload { id: byte };
48 }
49 MSG_M1_BRAKE | MSG_M2_BRAKE | MSG_PING => {
51 self.state = State::WaitChecksum {
52 id: byte,
53 payload: None,
54 };
55 }
56 _ => {
57 self.state = State::WaitStart;
59 }
60 }
61 }
62 State::WaitPayload { id } => {
63 self.checksum = self.checksum.wrapping_add(byte);
64 self.state = State::WaitChecksum {
65 id,
66 payload: Some(byte),
67 };
68 }
69 State::WaitChecksum { id, payload } => {
70 let valid = byte == self.checksum;
72 self.state = State::WaitStart; if valid {
75 return match (id, payload) {
76 (MSG_M1_EXTEND, Some(p)) => Some(Command::M1Extend(p)),
77 (MSG_M1_RETRACT, Some(p)) => Some(Command::M1Retract(p)),
78 (MSG_M1_BRAKE, None) => Some(Command::M1Brake),
79 (MSG_M1_SET_POSITION, Some(p)) => Some(Command::M1SetPosition(p)),
80 (MSG_M2_EXTEND, Some(p)) => Some(Command::M2Extend(p)),
81 (MSG_M2_RETRACT, Some(p)) => Some(Command::M2Retract(p)),
82 (MSG_M2_BRAKE, None) => Some(Command::M2Brake),
83 (MSG_M2_SET_POSITION, Some(p)) => Some(Command::M2SetPosition(p)),
84 (MSG_PING, None) => Some(Command::Ping),
85 _ => None,
86 };
87 }
88 }
89 }
90 None
91 }
92}