mqtt_tiny/packets/
subscribe.rs1use crate::anyvec::AnyVec;
4use crate::coding::encoder::{PacketLenIter, TopicsQosIter, U16Iter, 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;
11use core::marker::PhantomData;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct Subscribe<Seq, Bytes> {
16 packet_id: u16,
18 topics_qos: Seq,
26 _vec: PhantomData<Bytes>,
28}
29impl<Seq, Bytes> Subscribe<Seq, Bytes>
30where
31 Seq: AnyVec<(Bytes, u8)>,
32 Bytes: AnyVec<u8>,
33{
34 pub const TYPE: u8 = 8;
36
37 pub fn new<S, T>(packet_id: u16, topics: S) -> Result<Self, MemoryError>
45 where
46 S: IntoIterator<Item = (T, u8)>,
47 T: AsRef<[u8]>,
48 {
49 let mut topics_qos = Seq::default();
51 for (topic, qos) in topics {
52 let topic = Bytes::new(topic.as_ref())?;
54 topics_qos.push((topic, qos))?;
55 }
56
57 Ok(Self { packet_id, topics_qos, _vec: PhantomData })
59 }
60
61 pub fn packet_id(&self) -> u16 {
63 self.packet_id
64 }
65
66 pub fn topics_qos(&self) -> &Seq {
68 &self.topics_qos
69 }
70}
71impl<Seq, Bytes> TryFromIterator for Subscribe<Seq, Bytes>
72where
73 Seq: AnyVec<(Bytes, u8)>,
74 Bytes: AnyVec<u8>,
75{
76 fn try_from_iter<T>(iter: T) -> Result<Self, DecoderError>
77 where
78 T: IntoIterator<Item = u8>,
79 {
80 let mut decoder = Decoder::new(iter);
88 let (Self::TYPE, [false, false, true, false]) = decoder.header()? else {
89 return Err(err!(Data::SpecViolation, "invalid packet type/header"))?;
90 };
91 let len = decoder.packetlen()?;
93 let mut decoder = decoder.limit(len).peekable();
94 let packet_id = decoder.u16()?;
96 let topics_qos = decoder.topics_qos()?;
97
98 Ok(Self { packet_id, topics_qos, _vec: PhantomData })
100 }
101}
102impl<Seq, Bytes> IntoIterator for Subscribe<Seq, Bytes>
103where
104 Seq: AnyVec<(Bytes, u8)>,
105 Bytes: AnyVec<u8>,
106{
107 type Item = u8;
108 #[rustfmt::skip]
109 type IntoIter =
110 Chain<Chain<Chain<Chain<
112 Unit, U8Iter>,
114 PacketLenIter>,
116 U16Iter>,
118 TopicsQosIter<Seq, Bytes>>;
122
123 fn into_iter(self) -> Self::IntoIter {
124 #[rustfmt::skip]
130 let len = Length::new()
131 .u16(&self.packet_id)
132 .topics_qos(&self.topics_qos)
133 .into();
134
135 Encoder::default()
143 .header(Self::TYPE, [false, false, true, false])
144 .packetlen(len)
145 .u16(self.packet_id)
146 .topics_qos(self.topics_qos)
147 .into_iter()
148 }
149}