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
use std_alloc::{string::{String, ToString},
vec::Vec};
pub use crate::no_alloc::{Code, Id, Token, TokenLength, Type, Version};
use crate::{no_alloc::Byte1, from_bytes::*};
#[doc(hidden)]
pub mod opt;
#[doc(inline)]
pub use opt::*;
mod impl_get_size;
mod impl_to_bytes;
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct Payload(pub Vec<u8>);
#[doc = include_str!("../../docs/no_alloc/Message.md")]
#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub struct Message {
pub id: Id,
pub ty: Type,
pub ver: Version,
pub tkl: TokenLength,
pub token: Token,
pub code: Code,
pub opts: Vec<opt::Opt>,
pub payload: Payload,
}
impl<'a> TryFromBytes<&'a u8> for Message {
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 TryFromBytes<u8> for Message {
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.0 > 8 {
return Err(Self::Error::InvalidTokenLength(tkl.0 as u8));
}
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.0 as usize))?;
let opts = Vec::<Opt>::try_consume_bytes(&mut bytes).map_err(Self::Error::OptParseError)?;
let payload = Payload(bytes.collect());
Ok(Message { tkl,
id,
ty,
ver,
code,
token,
opts,
payload })
}
}
impl ToString for Code {
fn to_string(&self) -> String {
String::from_iter(self.to_human())
}
}
#[cfg(test)]
pub(self) fn test_msg() -> (Message, Vec<u8>) {
let header: [u8; 4] = 0b01_00_0001_01000101_0000000000000001u32.to_be_bytes();
let token: [u8; 1] = [254u8];
let content_format: &[u8] = b"application/json";
let options: [&[u8]; 2] = [&[0b_1100_1101u8, 0b00000011u8], content_format];
let payload: [&[u8]; 2] = [&[0b_11111111u8], b"hello, world!"];
let bytes = [header.as_ref(),
token.as_ref(),
options.concat().as_ref(),
payload.concat().as_ref()].concat();
let mut opts = Vec::new();
let opt = Opt { delta: OptDelta(12),
value: OptValue(content_format.iter().copied().collect()) };
opts.push(opt);
let msg = Message { id: Id(1),
ty: Type(0),
ver: Version(1),
token: Token(254),
tkl: TokenLength(1),
opts,
code: Code { class: 2, detail: 5 },
payload: Payload(b"hello, world!".into_iter().copied().collect()) };
(msg, bytes)
}