1use crate::mqtt4::QoS;
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
6pub struct PacketIdentifier(pub u16);
7
8impl From<u16> for PacketIdentifier {
9 fn from(value: u16) -> Self {
10 PacketIdentifier(value)
11 }
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Protocol {
17 MQTT(u8),
18}
19
20#[derive(Clone, PartialEq)]
22pub struct Connect {
23 pub protocol: Protocol,
25 pub keep_alive: u16,
27 pub client_id: String,
29 pub clean_session: bool,
31 pub last_will: Option<LastWill>,
33 pub username: Option<String>,
35 pub password: Option<String>,
37}
38
39impl Connect {
40 pub fn new<S: Into<String>>(id: S) -> Connect {
42 Connect {
43 protocol: Protocol::MQTT(4),
44 keep_alive: 10,
45 client_id: id.into(),
46 clean_session: true,
47 last_will: None,
48 username: None,
49 password: None,
50 }
51 }
52
53 pub fn set_username<S: Into<String>>(&mut self, u: S) -> &mut Connect {
55 self.username = Some(u.into());
56 self
57 }
58
59 pub fn set_password<S: Into<String>>(&mut self, p: S) -> &mut Connect {
61 self.password = Some(p.into());
62 self
63 }
64
65 pub(crate) fn len(&self) -> usize {
66 let mut len = 8 + "MQTT".len() + self.client_id.len();
67
68 if let Some(ref last_will) = self.last_will {
70 len += 4 + last_will.topic.len() + last_will.message.len();
71 }
72
73 if let Some(ref username) = self.username {
75 len += 2 + username.len();
76 }
77
78 if let Some(ref password) = self.password {
80 len += 2 + password.len();
81 }
82
83 len
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq)]
89#[repr(u8)]
90pub enum ConnectReturnCode {
91 Accepted = 0,
92 RefusedProtocolVersion,
93 RefusedIdentifierRejected,
94 ServerUnavailable,
95 BadUsernamePassword,
96 NotAuthorized,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq)]
101pub struct Connack {
102 pub session_present: bool,
103 pub code: ConnectReturnCode,
104}
105
106impl Connack {
107 pub fn new(code: ConnectReturnCode, session_present: bool) -> Connack {
109 Connack { code, session_present }
110 }
111}
112
113#[derive(Debug, Clone, PartialEq)]
115pub struct LastWill {
116 pub topic: String,
117 pub message: String,
118 pub qos: QoS,
119 pub retain: bool,
120}
121
122#[derive(Clone, PartialEq)]
124pub struct Publish {
125 pub dup: bool,
126 pub qos: QoS,
127 pub retain: bool,
128 pub topic_name: String,
129 pub pkid: Option<PacketIdentifier>,
130 pub payload: Vec<u8>,
131}
132
133impl Publish {
134 pub fn new<S: Into<String>, P: Into<Vec<u8>>>(topic: S, qos: QoS, payload: P) -> Publish {
137 Publish {
138 dup: false,
139 qos,
140 retain: false,
141 pkid: None,
142 topic_name: topic.into(),
143 payload: payload.into(),
144 }
145 }
146
147 pub fn set_pkid<P: Into<PacketIdentifier>>(&mut self, pkid: P) -> &mut Self {
149 self.pkid = Some(pkid.into());
150 self
151 }
152 pub fn set_retain(&mut self, retain: bool) -> &mut Self {
153 self.retain = retain;
154 self
155 }
156}
157
158#[derive(Clone, PartialEq)]
160pub struct Subscribe {
161 pub pkid: PacketIdentifier,
162 pub topics: Vec<SubscribeTopic>,
163}
164
165impl Subscribe {
166 pub fn new<S: Into<String>>(topic: S, qos: QoS) -> Subscribe {
169 let topic = SubscribeTopic {
170 topic_path: topic.into(),
171 qos,
172 };
173
174 Subscribe {
175 pkid: PacketIdentifier(0),
176 topics: vec![topic],
177 }
178 }
179
180 pub fn empty_subscribe() -> Subscribe {
182 Subscribe {
183 pkid: PacketIdentifier(0),
184 topics: Vec::new(),
185 }
186 }
187
188 pub fn add(&mut self, topic: String, qos: QoS) -> &mut Self {
189 let topic = SubscribeTopic { topic_path: topic, qos };
190 self.topics.push(topic);
191 self
192 }
193}
194
195#[derive(Clone, PartialEq)]
197pub struct SubscribeTopic {
198 pub topic_path: String,
199 pub qos: QoS,
200}
201
202#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204pub enum SubscribeReturnCodes {
205 Success(QoS),
206 Failure,
207}
208
209#[derive(Debug, Clone, PartialEq)]
211pub struct Suback {
212 pub pkid: PacketIdentifier,
213 pub return_codes: Vec<SubscribeReturnCodes>,
214}
215
216impl Suback {
217 pub fn new(pkid: PacketIdentifier, return_codes: Vec<SubscribeReturnCodes>) -> Suback {
219 Suback { pkid, return_codes }
220 }
221}
222
223#[derive(Debug, Clone, PartialEq)]
225pub struct Unsubscribe {
226 pub pkid: PacketIdentifier,
227 pub topics: Vec<String>,
228}
229
230impl fmt::Debug for Publish {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 write!(
233 f,
234 "Topic = {}, Qos = {:?}, Retain = {}, Pkid = {:?}, Payload Size = {}",
235 self.topic_name,
236 self.qos,
237 self.retain,
238 self.pkid,
239 self.payload.len()
240 )
241 }
242}
243
244impl fmt::Debug for Connect {
245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 write!(
247 f,
248 "Protocol = {:?}, Keep alive = {:?}, Client id = {}, Clean session = {}",
249 self.protocol, self.keep_alive, self.client_id, self.clean_session,
250 )
251 }
252}
253
254impl fmt::Debug for Subscribe {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 write!(f, "Filters = {:?}, Packet id = {:?}", self.pkid, self.topics)
257 }
258}
259
260impl fmt::Debug for SubscribeTopic {
261 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262 write!(f, "Filter = {}, Qos = {:?}", self.topic_path, self.qos)
263 }
264}