1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use super::*;
use crate::is_full::IsFull;
impl<'a, const PAYLOAD_CAP: usize, const N_OPTS: usize, const OPT_CAP: usize> TryFromBytes<&'a u8>
for Message<PAYLOAD_CAP, N_OPTS, OPT_CAP>
{
type Error = MessageParseError;
fn try_from_bytes<I: IntoIterator<Item = &'a u8>>(bytes: I) -> Result<Self, Self::Error> {
Self::try_from_bytes(bytes.into_iter().copied())
}
}
impl<const PAYLOAD_CAP: usize, const N_OPTS: usize, const OPT_CAP: usize> TryFromBytes<u8>
for Message<PAYLOAD_CAP, N_OPTS, OPT_CAP>
{
type Error = MessageParseError;
fn try_from_bytes<I: IntoIterator<Item = u8>>(bytes: I) -> Result<Self, Self::Error> {
let mut bytes = bytes.into_iter();
let Byte1 { tkl, ty, ver } = Self::Error::try_next(&mut bytes)?.into();
if tkl > 8 {
return Err(Self::Error::InvalidTokenLength(tkl));
}
let code: Code = Self::Error::try_next(&mut bytes)?.into();
let id: Id = Id::try_consume_bytes(&mut bytes)?;
let token = Token::try_consume_bytes(&mut bytes.by_ref().take(tkl as usize))?;
let opts = ArrayVec::<[Opt<OPT_CAP>; N_OPTS]>::try_consume_bytes(&mut bytes).map_err(Self::Error::OptParseError)?;
let mut payload_bytes = ArrayVec::new();
for byte in bytes {
if let Some(_) = payload_bytes.try_push(byte) {
return Err(Self::Error::PayloadTooLong(PAYLOAD_CAP));
}
}
let payload = Payload(payload_bytes);
Ok(Message { id,
ty,
ver,
code,
token,
opts,
payload })
}
}
impl From<u8> for Byte1 {
fn from(b: u8) -> Self {
let ver = b >> 6;
let ty = b >> 4 & 0b11;
let tkl = b & 0b1111u8;
Byte1 { ver: Version(ver),
ty: Type(ty),
tkl }
}
}
impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Id {
type Error = MessageParseError;
fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
let taken_bytes = bytes.take(2).collect::<ArrayVec<[_; 2]>>();
if taken_bytes.is_full() {
Ok(taken_bytes.into_inner()).map(|bs| Id(u16::from_be_bytes(bs)))
} else {
Err(MessageParseError::UnexpectedEndOfStream)
}
}
}
impl<I: Iterator<Item = u8>> TryConsumeBytes<I> for Token {
type Error = MessageParseError;
fn try_consume_bytes(bytes: &mut I) -> Result<Self, Self::Error> {
let token = bytes.into_iter().collect::<ArrayVec<[_; 8]>>();
Ok(Token(token))
}
}
impl From<u8> for Code {
fn from(b: u8) -> Self {
let class = b >> 5;
let detail = b & 0b0011111;
Code { class, detail }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_msg() {
let (expect, msg) = super::super::test_msg();
assert_eq!(Message::<13, 1, 16>::try_from_bytes(&msg).unwrap(), expect)
}
#[test]
fn parse_byte1() {
let byte = 0b_01_10_0011u8;
let byte = Byte1::from(byte);
assert_eq!(byte,
Byte1 { ver: Version(1),
ty: Type(2),
tkl: 3 })
}
#[test]
fn parse_id() {
let id_bytes = 34u16.to_be_bytes();
let id = Id::try_consume_bytes(&mut id_bytes.iter().copied()).unwrap();
assert_eq!(id, Id(34));
}
#[test]
fn parse_code() {
let byte = 0b_01_000101u8;
let code = Code::from(byte);
assert_eq!(code, Code { class: 2, detail: 5 })
}
#[test]
fn parse_token() {
let valid_a: [u8; 1] = [0b_00000001u8];
let valid_a = Token::try_consume_bytes(&mut valid_a.iter().copied()).unwrap();
assert_eq!(valid_a, Token(tinyvec::array_vec!([u8; 8] => 1)));
}
}