mqtt_tiny/packets/
publish.rs1use crate::anyvec::AnyVec;
4use crate::coding::encoder::{BytesIter, OptionalU16Iter, PacketLenIter, U8Iter, Unit};
5use crate::coding::length::Length;
6use crate::coding::{Decoder, Encoder};
7use crate::err;
8use crate::error::{Data, DecoderError, MemoryError};
9use crate::packets::TryFromIterator;
10use core::iter::Chain;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct Publish<Bytes> {
15 dup: bool,
17 qos: u8,
25 retain: bool,
27 topic: Bytes,
29 packet_id: Option<u16>,
31 payload: Bytes,
33}
34impl<Bytes> Publish<Bytes>
35where
36 Bytes: AnyVec<u8>,
37{
38 pub const TYPE: u8 = 3;
40
41 pub fn new<T, P>(topic: T, payload: P, retain: bool) -> Result<Self, MemoryError>
43 where
44 T: AsRef<[u8]>,
45 P: AsRef<[u8]>,
46 {
47 let topic = Bytes::new(topic.as_ref())?;
48 let payload = Bytes::new(payload.as_ref())?;
49 Ok(Self { dup: false, qos: 0, retain, topic, packet_id: None, payload })
50 }
51 pub fn with_qos(mut self, qos: u8, packet_id: u16, dup: bool) -> Self {
60 self.dup = dup;
61 self.qos = qos;
62 self.packet_id = Some(packet_id);
63 self
64 }
65
66 pub fn topic(&self) -> &[u8] {
68 self.topic.as_ref()
69 }
70
71 pub fn payload(&self) -> &[u8] {
73 self.payload.as_ref()
74 }
75
76 pub fn retain(&self) -> bool {
78 self.retain
79 }
80
81 pub fn dup(&self) -> bool {
83 self.dup
84 }
85 pub fn qos(&self) -> u8 {
87 self.qos
88 }
89 pub fn packet_id(&self) -> Option<u16> {
91 self.packet_id
92 }
93}
94impl<Bytes> TryFromIterator for Publish<Bytes>
95where
96 Bytes: AnyVec<u8>,
97{
98 fn try_from_iter<T>(iter: T) -> Result<Self, DecoderError>
99 where
100 T: IntoIterator<Item = u8>,
101 {
102 let mut decoder = Decoder::new(iter);
108 let (Self::TYPE, [dup, qos0, qos1, retain]) = decoder.header()? else {
109 return Err(err!(Data::SpecViolation, "invalid packet type"))?;
110 };
111 let len = decoder.packetlen()?;
113 let mut decoder = decoder.limit(len);
114 let topic = decoder.bytes()?;
116 let packet_id = decoder.optional_u16(qos0 || qos1)?;
117 let payload = decoder.raw_remainder()?;
118
119 let qos = ((qos0 as u8) << 1) | (qos1 as u8);
121 Ok(Self { dup, qos, retain, topic, packet_id, payload })
122 }
123}
124impl<Bytes> IntoIterator for Publish<Bytes>
125where
126 Bytes: AnyVec<u8>,
127{
128 type Item = u8;
129 #[rustfmt::skip]
130 type IntoIter =
131 Chain<Chain<Chain<Chain<Chain<
133 Unit, U8Iter>,
135 PacketLenIter>,
137 BytesIter<Bytes>>,
139 OptionalU16Iter>,
141 <Bytes as IntoIterator>::IntoIter>;
143
144 fn into_iter(self) -> Self::IntoIter {
145 #[rustfmt::skip]
147 let flags = [
148 self.dup,
149 (self.qos >> 1) != 0,
150 (self.qos & 1) != 0,
151 self.retain
152 ];
153
154 #[rustfmt::skip]
159 let len = Length::new()
160 .bytes(&self.topic)
161 .optional_u16(&self.packet_id)
162 .raw(&self.payload)
163 .into();
164
165 Encoder::default()
172 .header(Self::TYPE, flags)
173 .packetlen(len)
174 .bytes(self.topic)
175 .optional_u16(self.packet_id)
176 .raw(self.payload)
177 .into_iter()
178 }
179}