embedded_mqtt/payload/
mod.rs

1use core::{
2	result::Result,
3	default::Default,
4};
5
6use crate::{
7	fixed_header::PacketType,
8	codec::{Decodable, Encodable},
9	error::{DecodeError, EncodeError},
10	status::Status,
11};
12
13pub mod connect;
14pub mod subscribe;
15pub mod suback;
16
17#[derive(Debug)]
18pub enum Payload<'a> {
19	Bytes(&'a [u8]),
20	Connect(connect::Connect<'a>),
21	Subscribe(subscribe::Subscribe<'a>),
22	Suback(suback::Suback<'a>),
23}
24
25impl<'a> Payload<'a> {
26	pub fn decode(r#type: PacketType, bytes: &'a [u8]) -> Option<Result<Status<(usize, Self)>, DecodeError>> {
27		Some(match r#type {
28			// TODO need to pass the variable header / flags to the payload parser
29			//PacketType::Connect => Payload::Connect(complete!(connect::Connect::decode(bytes))),
30			PacketType::Suback => {
31				match suback::Suback::decode(bytes) {
32					Err(e) => Err(e),
33					Ok(Status::Partial(p)) => Ok(Status::Partial(p)),
34					Ok(Status::Complete((offset, p))) => {
35						Ok(Status::Complete((offset, Payload::Suback(p))))
36					},
37				}
38			},
39			PacketType::Subscribe => {
40				match subscribe::Subscribe::decode(bytes) {
41					Err(e) => Err(e),
42					Ok(Status::Partial(p)) => Ok(Status::Partial(p)),
43					Ok(Status::Complete((offset, p))) => {
44						Ok(Status::Complete((offset, Payload::Subscribe(p))))
45					},
46				}
47			},
48			_ => return None,
49		})
50	}
51}
52
53impl<'a> Encodable for Payload<'a> {
54	fn encoded_len(&self) -> usize {
55		match self {
56			&Payload::Connect(ref c)   => c.encoded_len(),
57			&Payload::Subscribe(ref c) => c.encoded_len(),
58			&Payload::Suback(ref c)    => c.encoded_len(),
59			&Payload::Bytes(ref c)     => c.len(),
60		}
61	}
62
63	fn encode(&self, bytes: &mut [u8]) -> Result<usize, EncodeError> {
64		match self {
65			&Payload::Connect(ref c)   => c.encode(bytes),
66			&Payload::Subscribe(ref c) => c.encode(bytes),
67			&Payload::Suback(ref c)    => c.encode(bytes),
68			&Payload::Bytes(ref c)   => {
69				if bytes.len() < c.len() {
70					return Err(EncodeError::OutOfSpace)
71				}
72
73				(&mut bytes[0..c.len()]).copy_from_slice(c);
74
75				Ok(c.len())
76			},
77		}
78	}
79}
80
81impl<'a> Default for Payload<'a> {
82	fn default() -> Self {
83		Payload::Bytes(&[])
84	}
85}