1use tinyvec::ArrayVec;
2
3use crate::*;
4
5pub trait TryFromBytes<T>: Sized {
7 type Error;
9
10 fn try_from_bytes<I: IntoIterator<Item = T>>(bytes: I) -> Result<Self, Self::Error>;
13}
14
15pub(crate) trait TryConsumeBytes<I: Iterator<Item = u8>>: Sized {
17 type Error;
19
20 fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error>;
23}
24
25pub(crate) trait TryConsumeNBytes<I: Iterator<Item = u8>>: Sized {
27 type Error;
29
30 fn try_consume_n_bytes(n: usize, bytes: &mut I) -> Result<Self, Self::Error>;
33}
34
35#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
37pub enum OptParseError {
38 UnexpectedEndOfStream,
40
41 OptionValueTooLong { capacity: usize, actual: usize },
43
44 TooManyOptions(usize),
46
47 OptionDeltaReservedValue(u8),
49
50 ValueLengthReservedValue(u8),
52
53 OptionsExhausted,
56}
57
58impl OptParseError {
59 pub(super) fn try_next<I>(mut iter: impl Iterator<Item = I>) -> Result<I, Self> {
60 iter.next().ok_or(Self::UnexpectedEndOfStream)
61 }
62}
63
64#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
66pub enum MessageParseError {
67 UnexpectedEndOfStream,
69
70 InvalidTokenLength(u8),
72
73 OptParseError(OptParseError),
75
76 PayloadTooLong(usize),
78
79 InvalidType(u8),
81}
82
83impl MessageParseError {
84 pub(super) fn try_next<I>(iter: &mut impl Iterator<Item = I>) -> Result<I, Self> {
85 iter.next().ok_or(Self::UnexpectedEndOfStream)
86 }
87}
88
89#[doc = include_str!("../docs/parsing/opt_len_or_delta.md")]
90pub(crate) fn parse_opt_len_or_delta(head: u8,
91 bytes: impl Iterator<Item = u8>,
92 reserved_err: OptParseError)
93 -> Result<u16, OptParseError> {
94 if head == 15 {
95 return Err(reserved_err);
96 }
97
98 match head {
99 | 13 => {
100 let n = OptParseError::try_next(bytes)?;
101 Ok((n as u16) + 13)
102 },
103 | 14 => {
104 let taken_bytes = bytes.take(2).collect::<tinyvec::ArrayVec<[u8; 2]>>();
105 if taken_bytes.is_full() {
106 Ok(u16::from_be_bytes(taken_bytes.into_inner()) + 269)
107 } else {
108 Err(OptParseError::UnexpectedEndOfStream)
109 }
110 },
111 | _ => Ok(head as u16),
112 }
113}
114
115impl TryFrom<u8> for Type {
116 type Error = MessageParseError;
117
118 fn try_from(b: u8) -> Result<Self, Self::Error> {
119 match b {
120 | 0 => Ok(Type::Con),
121 | 1 => Ok(Type::Non),
122 | 2 => Ok(Type::Ack),
123 | 3 => Ok(Type::Reset),
124 | _ => Err(MessageParseError::InvalidType(b)),
125 }
126 }
127}
128
129impl TryFrom<u8> for Byte1 {
130 type Error = MessageParseError;
131
132 fn try_from(b: u8) -> Result<Self, Self::Error> {
133 let ver = b >> 6; let ty = b >> 4 & 0b11; let tkl = b & 0b1111u8; Ok(Byte1 { ver: Version(ver),
138 ty: Type::try_from(ty)?,
139 tkl })
140 }
141}
142
143impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Id {
144 type Error = MessageParseError;
145
146 fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
147 let taken_bytes = bytes.take(2).collect::<ArrayVec<[_; 2]>>();
148
149 if taken_bytes.is_full() {
150 Ok(taken_bytes.into_inner()).map(|bs| Id(u16::from_be_bytes(bs)))
151 } else {
152 Err(MessageParseError::UnexpectedEndOfStream)
153 }
154 }
155}
156
157impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Token {
158 type Error = MessageParseError;
159
160 fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
161 let token = bytes.into_iter().collect::<ArrayVec<[_; 8]>>();
162
163 Ok(Token(token))
164 }
165}
166
167impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for OptDelta {
168 type Error = OptParseError;
169
170 fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
171 let first_byte = Self::Error::try_next(bytes.by_ref())?;
172 let delta = first_byte >> 4;
173 let delta = parse_opt_len_or_delta(delta, bytes, OptParseError::OptionDeltaReservedValue(15))?;
174
175 Ok(OptDelta(delta))
176 }
177}
178
179impl<'a, P: Array<Item = u8>, O: Array<Item = u8>, Os: Array<Item = Opt<O>>> TryFromBytes<&'a u8>
180 for Message<P, O, Os>
181{
182 type Error = MessageParseError;
183
184 fn try_from_bytes<I: IntoIterator<Item = &'a u8>>(bytes: I) -> Result<Self, Self::Error> {
185 Self::try_from_bytes(bytes.into_iter().copied())
186 }
187}
188
189impl<P: Array<Item = u8>, O: Array<Item = u8>, Os: Array<Item = Opt<O>>> TryFromBytes<u8>
190 for Message<P, O, Os>
191{
192 type Error = MessageParseError;
193
194 fn try_from_bytes<I: IntoIterator<Item = u8>>(bytes: I) -> Result<Self, Self::Error> {
195 let mut bytes = bytes.into_iter();
196
197 let Byte1 { tkl, ty, ver } = Self::Error::try_next(&mut bytes)?.try_into()?;
198
199 if tkl > 8 {
200 return Err(Self::Error::InvalidTokenLength(tkl));
201 }
202
203 let code: Code = Self::Error::try_next(&mut bytes)?.into();
204 let id: Id = Id::try_consume_bytes(&mut bytes)?;
205 let token = Token::try_consume_bytes(&mut bytes.by_ref().take(tkl as usize))?;
206 let opts = Os::try_consume_bytes(&mut bytes).map_err(Self::Error::OptParseError)?;
207 let payload = Payload(bytes.collect());
208
209 Ok(Message { id,
210 ty,
211 ver,
212 code,
213 token,
214 opts,
215 payload })
216 }
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn parse_msg() {
225 let (expect, msg) = crate::test_msg();
226 assert_eq!(VecMessage::try_from_bytes(&msg).unwrap(), expect)
227 }
228
229 #[test]
230 fn parse_byte1() {
231 let byte = 0b_01_10_0011u8;
232 let byte = Byte1::try_from(byte).unwrap();
233 assert_eq!(byte,
234 Byte1 { ver: Version(1),
235 ty: Type::Ack,
236 tkl: 3 })
237 }
238
239 #[test]
240 fn parse_id() {
241 let id_bytes = 34u16.to_be_bytes();
242 let id = Id::try_consume_bytes(&mut id_bytes.iter().copied()).unwrap();
243 assert_eq!(id, Id(34));
244 }
245
246 #[test]
247 fn parse_token() {
248 let valid_a: [u8; 1] = [0b0000_0001_u8];
249 let valid_a = Token::try_consume_bytes(&mut valid_a.iter().copied()).unwrap();
250 assert_eq!(valid_a, Token(tinyvec::array_vec!([u8; 8] => 1)));
251 }
252}