mqtt_tiny/packets/
unsubscribe.rs1use crate::anyvec::AnyVec;
4use crate::coding::encoder::{PacketLenIter, TopicsIter, 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 Unsubscribe<Seq, Bytes> {
16 packet_id: u16,
18 topics: Seq,
20 _vec: PhantomData<Bytes>,
22}
23impl<Seq, Bytes> Unsubscribe<Seq, Bytes>
24where
25 Seq: AnyVec<Bytes>,
26 Bytes: AnyVec<u8>,
27{
28 pub const TYPE: u8 = 10;
30
31 pub fn new<S, T>(packet_id: u16, topics: S) -> Result<Self, MemoryError>
33 where
34 S: IntoIterator<Item = T>,
35 T: AsRef<[u8]>,
36 {
37 let mut topics_ = Seq::default();
39 for topic in topics {
40 let topic = Bytes::new(topic.as_ref())?;
42 topics_.push(topic)?;
43 }
44
45 Ok(Self { packet_id, topics: topics_, _vec: PhantomData })
47 }
48
49 pub fn packet_id(&self) -> u16 {
51 self.packet_id
52 }
53
54 pub fn topics(&self) -> &Seq {
56 &self.topics
57 }
58}
59impl<Seq, Bytes> TryFromIterator for Unsubscribe<Seq, Bytes>
60where
61 Seq: AnyVec<Bytes>,
62 Bytes: AnyVec<u8>,
63{
64 fn try_from_iter<T>(iter: T) -> Result<Self, DecoderError>
65 where
66 T: IntoIterator<Item = u8>,
67 {
68 let mut decoder = Decoder::new(iter);
75 let (Self::TYPE, [false, false, true, false]) = decoder.header()? else {
76 return Err(err!(Data::SpecViolation, "invalid packet type/header"))?;
77 };
78 let len = decoder.packetlen()?;
80 let mut decoder = decoder.limit(len).peekable();
81 let packet_id = decoder.u16()?;
83 let topics = decoder.topics()?;
84
85 Ok(Self { packet_id, topics, _vec: PhantomData })
87 }
88}
89impl<Seq, Bytes> IntoIterator for Unsubscribe<Seq, Bytes>
90where
91 Seq: AnyVec<Bytes>,
92 Bytes: AnyVec<u8>,
93{
94 type Item = u8;
95 #[rustfmt::skip]
96 type IntoIter =
97 Chain<Chain<Chain<Chain<
99 Unit, U8Iter>,
101 PacketLenIter>,
103 U16Iter>,
105 TopicsIter<Seq, Bytes>>;
108
109 fn into_iter(self) -> Self::IntoIter {
110 #[rustfmt::skip]
115 let len = Length::new()
116 .u16(&self.packet_id)
117 .topics(&self.topics)
118 .into();
119
120 Encoder::default()
127 .header(Self::TYPE, [false, false, true, false])
128 .packetlen(len)
129 .u16(self.packet_id)
130 .topics(self.topics)
131 .into_iter()
132 }
133}