kwap_msg/
from_bytes.rs

1use tinyvec::ArrayVec;
2
3use crate::*;
4
5/// Trait for converting a sequence of bytes into some data structure
6pub trait TryFromBytes<T>: Sized {
7  /// Error type yielded if conversion fails
8  type Error;
9
10  /// Try to convert from some sequence of bytes `T`
11  /// into `Self`
12  fn try_from_bytes<I: IntoIterator<Item = T>>(bytes: I) -> Result<Self, Self::Error>;
13}
14
15/// Trait adding the ability for a _piece_ of a data structure to parse itself by mutating an iterator over bytes.
16pub(crate) trait TryConsumeBytes<I: Iterator<Item = u8>>: Sized {
17  /// Error type yielded if conversion fails
18  type Error;
19
20  /// Try to convert from some sequence of bytes `T`
21  /// into `Self`
22  fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error>;
23}
24
25/// Similar to `TryConsumeBytes` except that the number of bytes to consume is determined by the caller.
26pub(crate) trait TryConsumeNBytes<I: Iterator<Item = u8>>: Sized {
27  /// Error type yielded if conversion fails
28  type Error;
29
30  /// Try to convert from some sequence of bytes `T`
31  /// into `Self`
32  fn try_consume_n_bytes(n: usize, bytes: &mut I) -> Result<Self, Self::Error>;
33}
34
35/// Errors encounterable while parsing an option from bytes
36#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
37pub enum OptParseError {
38  /// Reached end of stream before parsing was finished
39  UnexpectedEndOfStream,
40
41  /// Option value was longer than the fixed capacity
42  OptionValueTooLong { capacity: usize, actual: usize },
43
44  /// Parsed more options than reserved capacity
45  TooManyOptions(usize),
46
47  /// Option Delta was set to 15, which is invalid.
48  OptionDeltaReservedValue(u8),
49
50  /// Value Length was set to 15, which is invalid.
51  ValueLengthReservedValue(u8),
52
53  /// Not a true failure case; only means we tried to read the payload marker byte (0xFF)
54  /// as an option header.
55  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/// Errors encounterable while parsing a message from bytes
65#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
66pub enum MessageParseError {
67  /// Reached end of stream before parsing was finished
68  UnexpectedEndOfStream,
69
70  /// Token length was > 8
71  InvalidTokenLength(u8),
72
73  /// Error parsing option
74  OptParseError(OptParseError),
75
76  /// The rest of the message contained more bytes than there was capacity for
77  PayloadTooLong(usize),
78
79  /// The message type is invalid (see [`Type`] for information & valid values)
80  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; // bits 0 & 1
134    let ty = b >> 4 & 0b11; // bits 2 & 3
135    let tkl = b & 0b1111u8; // last 4 bits
136
137    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}