1use crate::{decoder::*, encoder::*, *};
2
3#[derive(Debug, Clone, PartialEq)]
7pub struct Publish<'a> {
8 pub dup: bool,
9 pub qospid: QosPid,
10 pub retain: bool,
11 pub topic_name: &'a str,
12 pub payload: &'a [u8],
13}
14
15impl<'a> Publish<'a> {
16 pub(crate) fn from_buffer(
17 header: &Header,
18 remaining_len: usize,
19 buf: &'a [u8],
20 offset: &mut usize,
21 ) -> Result<Self, Error> {
22 let payload_end = *offset + remaining_len;
23 let topic_name = read_str(buf, offset)?;
24
25 let qospid = match header.qos {
26 QoS::AtMostOnce => QosPid::AtMostOnce,
27 QoS::AtLeastOnce => QosPid::AtLeastOnce(Pid::from_buffer(buf, offset)?),
28 QoS::ExactlyOnce => QosPid::ExactlyOnce(Pid::from_buffer(buf, offset)?),
29 };
30
31 Ok(Publish {
32 dup: header.dup,
33 qospid,
34 retain: header.retain,
35 topic_name,
36 payload: &buf[*offset..payload_end],
37 })
38 }
39 pub(crate) fn to_buffer(&self, buf: &mut [u8], offset: &mut usize) -> Result<usize, Error> {
40 let mut header: u8 = match self.qospid {
42 QosPid::AtMostOnce => 0b00110000,
43 QosPid::AtLeastOnce(_) => 0b00110010,
44 QosPid::ExactlyOnce(_) => 0b00110100,
45 };
46 if self.dup {
47 header |= 0b00001000 as u8;
48 };
49 if self.retain {
50 header |= 0b00000001 as u8;
51 };
52 check_remaining(buf, offset, 1)?;
53 write_u8(buf, offset, header)?;
54
55 let length = self.topic_name.len()
57 + match self.qospid {
58 QosPid::AtMostOnce => 2,
59 _ => 4,
60 }
61 + self.payload.len();
62
63 let write_len = write_length(buf, offset, length)? + 1;
64
65 write_string(buf, offset, self.topic_name)?;
67
68 match self.qospid {
70 QosPid::AtMostOnce => (),
71 QosPid::AtLeastOnce(pid) => pid.to_buffer(buf, offset)?,
72 QosPid::ExactlyOnce(pid) => pid.to_buffer(buf, offset)?,
73 }
74
75 for &byte in self.payload {
77 write_u8(buf, offset, byte)?;
78 }
79
80 Ok(write_len)
81 }
82}