1use crate::anyvec::AnyVec;
4use crate::err;
5use crate::error::{Data, DecoderError};
6use crate::packets::connack::Connack;
7use crate::packets::connect::Connect;
8use crate::packets::disconnect::Disconnect;
9use crate::packets::pingreq::Pingreq;
10use crate::packets::pingresp::Pingresp;
11use crate::packets::puback::Puback;
12use crate::packets::pubcomp::Pubcomp;
13use crate::packets::publish::Publish;
14use crate::packets::pubrec::Pubrec;
15use crate::packets::pubrel::Pubrel;
16use crate::packets::suback::Suback;
17use crate::packets::subscribe::Subscribe;
18use crate::packets::unsuback::Unsuback;
19use crate::packets::unsubscribe::Unsubscribe;
20use crate::packets::TryFromIterator;
21
22#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum Packet<TopicsSeq, TopicsQosSeq, Bytes> {
25 Connack(Connack),
27 Connect(Connect<Bytes>),
29 Disconnect(Disconnect),
31 Pingreq(Pingreq),
33 Pingresp(Pingresp),
35 Puback(Puback),
37 Pubcomp(Pubcomp),
39 Publish(Publish<Bytes>),
41 Pubrec(Pubrec),
43 Pubrel(Pubrel),
45 Suback(Suback),
47 Subscribe(Subscribe<TopicsQosSeq, Bytes>),
49 Unsuback(Unsuback),
51 Unsubscribe(Unsubscribe<TopicsSeq, Bytes>),
53}
54impl<TopicsSeq, TopicsQosSeq, Bytes> TryFromIterator for Packet<TopicsSeq, TopicsQosSeq, Bytes>
55where
56 TopicsSeq: AnyVec<Bytes>,
57 TopicsQosSeq: AnyVec<(Bytes, u8)>,
58 Bytes: AnyVec<u8>,
59{
60 fn try_from_iter<T>(iter: T) -> Result<Self, DecoderError>
61 where
62 T: IntoIterator<Item = u8>,
63 {
64 let mut decoder = iter.into_iter().peekable();
66 let header = decoder.peek().ok_or(err!(Data::Truncated, "empty packet"))?;
67
68 match header >> 4 {
70 Connack::TYPE => Connack::try_from_iter(&mut decoder).map(Self::Connack),
71 Connect::<Bytes>::TYPE => Connect::try_from_iter(&mut decoder).map(Self::Connect),
72 Disconnect::TYPE => Disconnect::try_from_iter(&mut decoder).map(Self::Disconnect),
73 Pingreq::TYPE => Pingreq::try_from_iter(&mut decoder).map(Self::Pingreq),
74 Pingresp::TYPE => Pingresp::try_from_iter(&mut decoder).map(Self::Pingresp),
75 Puback::TYPE => Puback::try_from_iter(&mut decoder).map(Self::Puback),
76 Pubcomp::TYPE => Pubcomp::try_from_iter(&mut decoder).map(Self::Pubcomp),
77 Publish::<Bytes>::TYPE => Publish::try_from_iter(&mut decoder).map(Self::Publish),
78 Pubrec::TYPE => Pubrec::try_from_iter(&mut decoder).map(Self::Pubrec),
79 Pubrel::TYPE => Pubrel::try_from_iter(&mut decoder).map(Self::Pubrel),
80 Suback::TYPE => Suback::try_from_iter(&mut decoder).map(Self::Suback),
81 Subscribe::<TopicsQosSeq, Bytes>::TYPE => Subscribe::try_from_iter(&mut decoder).map(Self::Subscribe),
82 Unsuback::TYPE => Unsuback::try_from_iter(&mut decoder).map(Self::Unsuback),
83 Unsubscribe::<TopicsSeq, Bytes>::TYPE => Unsubscribe::try_from_iter(&mut decoder).map(Self::Unsubscribe),
84 _ => Err(err!(Data::SpecViolation, "unknown packet type"))?,
85 }
86 }
87}
88impl<TopicsSeq, TopicsQosSeq, Bytes> IntoIterator for Packet<TopicsSeq, TopicsQosSeq, Bytes>
89where
90 TopicsSeq: AnyVec<Bytes>,
91 TopicsQosSeq: AnyVec<(Bytes, u8)>,
92 Bytes: AnyVec<u8>,
93{
94 type Item = u8;
95 type IntoIter = PacketIter<TopicsSeq, TopicsQosSeq, Bytes>;
96
97 fn into_iter(self) -> Self::IntoIter {
98 match self {
99 Self::Connack(this) => PacketIter::Connack(this.into_iter()),
100 Self::Connect(this) => PacketIter::Connect(this.into_iter()),
101 Self::Disconnect(this) => PacketIter::Disconnect(this.into_iter()),
102 Self::Pingreq(this) => PacketIter::Pingreq(this.into_iter()),
103 Self::Pingresp(this) => PacketIter::Pingresp(this.into_iter()),
104 Self::Puback(this) => PacketIter::Puback(this.into_iter()),
105 Self::Pubcomp(this) => PacketIter::Pubcomp(this.into_iter()),
106 Self::Publish(this) => PacketIter::Publish(this.into_iter()),
107 Self::Pubrec(this) => PacketIter::Pubreq(this.into_iter()),
108 Self::Pubrel(this) => PacketIter::Pubrel(this.into_iter()),
109 Self::Suback(this) => PacketIter::Suback(this.into_iter()),
110 Self::Subscribe(this) => PacketIter::Subscribe(this.into_iter()),
111 Self::Unsuback(this) => PacketIter::Unsuback(this.into_iter()),
112 Self::Unsubscribe(this) => PacketIter::Unsubscribe(this.into_iter()),
113 }
114 }
115}
116
117pub enum PacketIter<TopicsSeq, TopicsQosSeq, Bytes>
119where
120 TopicsSeq: AnyVec<Bytes>,
121 TopicsQosSeq: AnyVec<(Bytes, u8)>,
122 Bytes: AnyVec<u8>,
123{
124 Connack(<Connack as IntoIterator>::IntoIter),
126 Connect(<Connect<Bytes> as IntoIterator>::IntoIter),
128 Disconnect(<Disconnect as IntoIterator>::IntoIter),
130 Pingreq(<Pingreq as IntoIterator>::IntoIter),
132 Pingresp(<Pingresp as IntoIterator>::IntoIter),
134 Puback(<Puback as IntoIterator>::IntoIter),
136 Pubcomp(<Pubcomp as IntoIterator>::IntoIter),
138 Publish(<Publish<Bytes> as IntoIterator>::IntoIter),
140 Pubreq(<Pubrec as IntoIterator>::IntoIter),
142 Pubrel(<Pubrel as IntoIterator>::IntoIter),
144 Suback(<Suback as IntoIterator>::IntoIter),
146 Subscribe(<Subscribe<TopicsQosSeq, Bytes> as IntoIterator>::IntoIter),
148 Unsuback(<Unsuback as IntoIterator>::IntoIter),
150 Unsubscribe(<Unsubscribe<TopicsSeq, Bytes> as IntoIterator>::IntoIter),
152}
153impl<TopicsSeq, TopicsQosSeq, Bytes> Iterator for PacketIter<TopicsSeq, TopicsQosSeq, Bytes>
154where
155 TopicsSeq: AnyVec<Bytes>,
156 TopicsQosSeq: AnyVec<(Bytes, u8)>,
157 Bytes: AnyVec<u8>,
158{
159 type Item = u8;
160
161 fn next(&mut self) -> Option<Self::Item> {
162 match self {
163 Self::Connack(iter) => iter.next(),
164 Self::Connect(iter) => iter.next(),
165 Self::Disconnect(iter) => iter.next(),
166 Self::Pingreq(iter) => iter.next(),
167 Self::Pingresp(iter) => iter.next(),
168 Self::Puback(iter) => iter.next(),
169 Self::Pubcomp(iter) => iter.next(),
170 Self::Publish(iter) => iter.next(),
171 Self::Pubreq(iter) => iter.next(),
172 Self::Pubrel(iter) => iter.next(),
173 Self::Suback(iter) => iter.next(),
174 Self::Subscribe(iter) => iter.next(),
175 Self::Unsuback(iter) => iter.next(),
176 Self::Unsubscribe(iter) => iter.next(),
177 }
178 }
179}