es51986/parser.rs
1use serde::{Deserialize, Serialize};
2
3use crate::{Output, OUTPUT_LENGTH};
4
5/// Parse errors
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub enum ParseError {
8 /// Length error. ES51986's data is 9 byte long followed by CRLF characters.
9 /// If the length is wrong, this error will be returned.
10 LengthError {
11 /// The length detected. If the data was '1234567890\r\n' then this 'len' will become 10.
12 len: usize
13 },
14 /// The first byte of the data is range. If the range byte is invalid, this error will be returned.
15 /// The u8 data is actual data byte.
16 InvalidRange(u8),
17 /// The 5th byte of the data is function. If the function is invalid, this error will be returned.
18 /// The u8 data is actual data byte.
19 InvalidFunction(u8),
20 /// The 1-4 byte of the data is digits. If the digits is invalid, this error will be returned.
21 /// The u8 data is actual data byte.
22 InvalidDigit(u8),
23}
24
25const CR: u8 = 0x0d;
26const LF: u8 = 0x0a;
27
28enum ParserState {
29 Idle,
30 FoundCr,
31}
32
33pub struct Parser {
34 state: ParserState,
35 buf: Vec<u8>,
36}
37
38impl Parser {
39 pub fn new() -> Self {
40 Self {
41 state: ParserState::Idle,
42 buf: vec![]
43 }
44 }
45
46 fn parse_ch(&mut self, ch: u8) -> Result<Option<Output>, ParseError> {
47 match self.state {
48 ParserState::Idle => {
49 if ch == CR {
50 self.state = ParserState::FoundCr;
51 let result = Output::parse(&self.buf);
52 self.buf.clear();
53 result.map(|o| Some(o))
54 } else if ch == LF {
55 self.state = ParserState::Idle;
56 let result = Output::parse(&self.buf);
57 self.buf.clear();
58 result.map(|o| Some(o))
59 } else {
60 self.buf.push(ch);
61 let len = self.buf.len();
62 if OUTPUT_LENGTH < len {
63 let drain_amount = len - OUTPUT_LENGTH;
64 self.buf.drain(..drain_amount);
65 Err(ParseError::LengthError { len })
66 } else {
67 Ok(None)
68 }
69 }
70 }
71 ParserState::FoundCr => {
72 if ch == LF {
73 self.buf.clear();
74 Ok(None)
75 } else {
76 self.buf.push(ch);
77 self.state = ParserState::Idle;
78 Ok(None)
79 }
80 }
81 }
82 }
83
84 /// Supply the data to the parser.
85 ///
86 /// The data to the parser is 11 bytes long that ends with CR (0x0d), LF (0x0a). 11 bytes may be given as a whole but you can supply smaller pieces (less than 11 bytes), or data exceeding 11 bytes may be given.
87 ///
88 /// # Argument
89 ///
90 /// * 'input' - Data to parse.
91 ///
92 ///
93 /// # Return value
94 ///
95 /// Vector of parsed result.
96 ///
97 /// # Examples
98 ///
99 /// Simple case.
100 /// ```
101 /// use es51986::{PrefixUnit, ValueUnit, BaseUnit};
102 ///
103 /// let mut parser = es51986::parser::Parser::new();
104 /// let input: Vec<u8> = "00000;<0:\r\n".chars().map(|c| c as u8).collect();
105 /// let results = parser.parse(&input);
106 /// assert_eq!(results.len(), 1);
107 /// let output = results[0].as_ref().unwrap();
108 /// let value = output.get_value().unwrap();
109 /// assert_eq!(&value.digits, "0.000");
110 /// assert_eq!(value.value_unit, ValueUnit { prefix_unit: PrefixUnit::None, base_unit: BaseUnit::Volt});
111 /// ```
112 ///
113 /// You can supply smaller chunks of data.
114 /// ```
115 /// use es51986::{PrefixUnit, ValueUnit, BaseUnit};
116 ///
117 /// let mut parser = es51986::parser::Parser::new();
118 /// let input: Vec<u8> = "01".chars().map(|c| c as u8).collect();
119 /// let results = parser.parse(&input);
120 /// assert_eq!(results.len(), 0); // Data is not completed yet.
121 /// let input: Vec<u8> = "234;<0:\r\n".chars().map(|c| c as u8).collect();
122 /// let results = parser.parse(&input);
123 /// assert_eq!(results.len(), 1);
124 /// let output = results[0].as_ref().unwrap();
125 /// let value = output.get_value().unwrap();
126 /// assert_eq!(&value.digits, "1.234");
127 /// assert_eq!(value.value_unit, ValueUnit { prefix_unit: PrefixUnit::None, base_unit: BaseUnit::Volt});
128 /// ```
129 /// You can supply larger data that contains multiple data.
130 /// ```
131 /// use es51986::{PrefixUnit, ValueUnit, BaseUnit};
132 ///
133 /// let mut parser = es51986::parser::Parser::new();
134 /// let input: Vec<u8> = "00000;<0:\r\n00000;<0:\r\n".chars().map(|c| c as u8).collect();
135 /// let results = parser.parse(&input);
136 /// assert_eq!(results.len(), 2);
137 /// let output = results[0].as_ref().unwrap();
138 /// let value = output.get_value().unwrap();
139 /// assert_eq!(&value.digits, "0.000");
140 /// assert_eq!(value.value_unit, ValueUnit { prefix_unit: PrefixUnit::None, base_unit: BaseUnit::Volt});
141 /// assert_eq!(results[0].as_ref().unwrap(), results[1].as_ref().unwrap());
142 /// ```
143 pub fn parse(&mut self, input: &[u8]) -> Vec<Result<Output, ParseError>> {
144 let mut results: Vec<Result<Output, ParseError>> = vec![];
145 for ch in input.iter() {
146 match self.parse_ch(*ch) {
147 Ok(Some(out)) => results.push(Ok(out)),
148 Ok(None) => {},
149 Err(err) => results.push(Err(err)),
150 }
151 }
152
153 results
154 }
155}