embedded_mqtt/payload/
mod.rs1use 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 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}