1use derive_builder::UninitializedFieldError;
25use num_enum::TryFromPrimitive;
26use serde::{Serialize, Serializer};
27use std::fmt;
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30#[repr(u16)]
31pub enum MqttError {
32 UnspecifiedError = 0x0080,
34 MalformedPacket = 0x0081,
35 ProtocolError = 0x0082,
36 ImplementationSpecificError = 0x0083,
37 UnsupportedProtocolVersion = 0x0084,
38 ClientIdentifierNotValid = 0x0085,
39 BadUserNameOrPassword = 0x0086,
40 NotAuthorized = 0x0087,
41 ServerUnavailable = 0x0088,
42 ServerBusy = 0x0089,
43 Banned = 0x008A,
44 ServerShuttingDown = 0x008B,
45 BadAuthenticationMethod = 0x008C,
46 KeepAliveTimeout = 0x008D,
47 SessionTakenOver = 0x008E,
48 TopicFilterInvalid = 0x008F,
49 TopicNameInvalid = 0x0090,
50 ReceiveMaximumExceeded = 0x0093,
51 TopicAliasInvalid = 0x0094,
52 PacketTooLarge = 0x0095,
53 MessageRateTooHigh = 0x0096,
54 QuotaExceeded = 0x0097,
55 AdministrativeAction = 0x0098,
56 PayloadFormatInvalid = 0x0099,
57 RetainNotSupported = 0x009A,
58 QosNotSupported = 0x009B,
59 UseAnotherServer = 0x009C,
60 ServerMoved = 0x009D,
61 SharedSubscriptionsNotSupported = 0x009E,
62 ConnectionRateExceeded = 0x009F,
63 MaximumConnectTime = 0x00A0,
64 SubscriptionIdentifiersNotSupported = 0x00A1,
65 WildcardSubscriptionsNotSupported = 0x00A2,
66
67 PartialErrorDetected = 0x0101,
69 PacketEnqueued = 0x0102,
70 AllErrorDetected = 0x0180,
71 PacketIdentifierFullyUsed = 0x0181,
72 PacketIdentifierConflict = 0x0182,
73 PacketIdentifierInvalid = 0x0183,
74 PacketNotAllowedToSend = 0x0184,
75 PacketNotAllowedToStore = 0x0185,
76 PacketNotRegulated = 0x0186,
77 InsufficientBytes = 0x0187,
78 InvalidPacketForRole = 0x0188,
79 VersionMismatch = 0x0189,
80 PacketConversionFailed = 0x018A,
81 PacketProcessFailed = 0x018B,
82 ValueOutOfRange = 0x018C,
83 InvalidQos = 0x018D,
84}
85
86impl From<UninitializedFieldError> for MqttError {
88 fn from(_: UninitializedFieldError) -> Self {
89 MqttError::MalformedPacket
91 }
92}
93
94impl From<std::convert::Infallible> for MqttError {
96 fn from(_: std::convert::Infallible) -> Self {
97 unreachable!()
99 }
100}
101
102impl std::fmt::Display for MqttError {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 let s = match self {
105 Self::UnspecifiedError => "UnspecifiedError",
106 Self::MalformedPacket => "MalformedPacket",
107 Self::ProtocolError => "ProtocolError",
108 Self::ImplementationSpecificError => "ImplementationSpecificError",
109 Self::UnsupportedProtocolVersion => "UnsupportedProtocolVersion",
110 Self::ClientIdentifierNotValid => "ClientIdentifierNotValid",
111 Self::BadUserNameOrPassword => "BadUserNameOrPassword",
112 Self::NotAuthorized => "NotAuthorized",
113 Self::ServerUnavailable => "ServerUnavailable",
114 Self::ServerBusy => "ServerBusy",
115 Self::Banned => "Banned",
116 Self::ServerShuttingDown => "ServerShuttingDown",
117 Self::BadAuthenticationMethod => "BadAuthenticationMethod",
118 Self::KeepAliveTimeout => "KeepAliveTimeout",
119 Self::SessionTakenOver => "SessionTakenOver",
120 Self::TopicFilterInvalid => "TopicFilterInvalid",
121 Self::TopicNameInvalid => "TopicNameInvalid",
122 Self::ReceiveMaximumExceeded => "ReceiveMaximumExceeded",
123 Self::TopicAliasInvalid => "TopicAliasInvalid",
124 Self::PacketTooLarge => "PacketTooLarge",
125 Self::MessageRateTooHigh => "MessageRateTooHigh",
126 Self::QuotaExceeded => "QuotaExceeded",
127 Self::AdministrativeAction => "AdministrativeAction",
128 Self::PayloadFormatInvalid => "PayloadFormatInvalid",
129 Self::RetainNotSupported => "RetainNotSupported",
130 Self::QosNotSupported => "QosNotSupported",
131 Self::UseAnotherServer => "UseAnotherServer",
132 Self::ServerMoved => "ServerMoved",
133 Self::SharedSubscriptionsNotSupported => "SharedSubscriptionsNotSupported",
134 Self::ConnectionRateExceeded => "ConnectionRateExceeded",
135 Self::MaximumConnectTime => "MaximumConnectTime",
136 Self::SubscriptionIdentifiersNotSupported => "SubscriptionIdentifiersNotSupported",
137 Self::WildcardSubscriptionsNotSupported => "WildcardSubscriptionsNotSupported",
138
139 Self::PartialErrorDetected => "PartialErrorDetected",
140 Self::PacketEnqueued => "PacketEnqueued",
141 Self::AllErrorDetected => "AllErrorDetected",
142 Self::PacketIdentifierFullyUsed => "PacketIdentifierFullyUsed",
143 Self::PacketIdentifierConflict => "PacketIdentifierConflict",
144 Self::PacketIdentifierInvalid => "PacketIdentifierInvalid",
145 Self::PacketNotAllowedToSend => "PacketNotAllowedToSend",
146 Self::PacketNotAllowedToStore => "PacketNotAllowedToStore",
147 Self::PacketNotRegulated => "PacketNotRegulated",
148 Self::InsufficientBytes => "InsufficientBytes",
149 Self::InvalidPacketForRole => "InvalidPacketForRole",
150 Self::VersionMismatch => "VersionMismatch",
151 Self::PacketConversionFailed => "PacketConversionFailed",
152 Self::PacketProcessFailed => "PacketProcessFailed",
153 Self::ValueOutOfRange => "ValueOutOfRange",
154 Self::InvalidQos => "InvalidQos",
155 };
156 write!(f, "{s}")
157 }
158}
159
160impl Serialize for MqttError {
161 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
162 where
163 S: Serializer,
164 {
165 serializer.serialize_str(&self.to_string())
166 }
167}
168
169impl core::convert::TryFrom<u8> for MqttError {
170 type Error = u8;
171
172 fn try_from(code: u8) -> Result<Self, Self::Error> {
173 match code {
174 0x80 => Ok(Self::UnspecifiedError),
175 0x81 => Ok(Self::MalformedPacket),
176 0x82 => Ok(Self::ProtocolError),
177 0x83 => Ok(Self::ImplementationSpecificError),
178 0x84 => Ok(Self::UnsupportedProtocolVersion),
179 0x85 => Ok(Self::ClientIdentifierNotValid),
180 0x86 => Ok(Self::BadUserNameOrPassword),
181 0x87 => Ok(Self::NotAuthorized),
182 0x88 => Ok(Self::ServerUnavailable),
183 0x89 => Ok(Self::ServerBusy),
184 0x8A => Ok(Self::Banned),
185 0x8B => Ok(Self::ServerShuttingDown),
186 0x8C => Ok(Self::BadAuthenticationMethod),
187 0x8D => Ok(Self::KeepAliveTimeout),
188 0x8E => Ok(Self::SessionTakenOver),
189 0x8F => Ok(Self::TopicFilterInvalid),
190 0x90 => Ok(Self::TopicNameInvalid),
191 0x93 => Ok(Self::ReceiveMaximumExceeded),
192 0x94 => Ok(Self::TopicAliasInvalid),
193 0x95 => Ok(Self::PacketTooLarge),
194 0x96 => Ok(Self::MessageRateTooHigh),
195 0x97 => Ok(Self::QuotaExceeded),
196 0x98 => Ok(Self::AdministrativeAction),
197 0x99 => Ok(Self::PayloadFormatInvalid),
198 0x9A => Ok(Self::RetainNotSupported),
199 0x9B => Ok(Self::QosNotSupported),
200 0x9C => Ok(Self::UseAnotherServer),
201 0x9D => Ok(Self::ServerMoved),
202 0x9E => Ok(Self::SharedSubscriptionsNotSupported),
203 0x9F => Ok(Self::ConnectionRateExceeded),
204 0xA0 => Ok(Self::MaximumConnectTime),
205 0xA1 => Ok(Self::SubscriptionIdentifiersNotSupported),
206 0xA2 => Ok(Self::WildcardSubscriptionsNotSupported),
207 other => Err(other),
208 }
209 }
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
214#[repr(u8)]
215pub enum ConnectReturnCode {
216 Accepted = 0, UnacceptableProtocolVersion = 1, IdentifierRejected = 2, ServerUnavailable = 3, BadUserNameOrPassword = 4, NotAuthorized = 5, }
223
224impl ConnectReturnCode {
225 pub fn is_success(&self) -> bool {
226 matches!(self, Self::Accepted)
227 }
228 pub fn is_failure(&self) -> bool {
229 !self.is_success()
230 }
231}
232
233impl fmt::Display for ConnectReturnCode {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 let s = match self {
236 Self::Accepted => "Accepted",
237 Self::UnacceptableProtocolVersion => "UnacceptableProtocolVersion",
238 Self::IdentifierRejected => "IdentifierRejected",
239 Self::ServerUnavailable => "ServerUnavailable",
240 Self::BadUserNameOrPassword => "BadUserNameOrPassword",
241 Self::NotAuthorized => "NotAuthorized",
242 };
243 write!(f, "{s}")
244 }
245}
246
247impl Serialize for ConnectReturnCode {
248 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
249 where
250 S: Serializer,
251 {
252 serializer.serialize_str(&self.to_string())
253 }
254}
255
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
258#[repr(u8)]
259pub enum SubackReturnCode {
260 SuccessMaximumQos0 = 0x00, SuccessMaximumQos1 = 0x01, SuccessMaximumQos2 = 0x02, Failure = 0x80, }
265
266impl SubackReturnCode {
267 pub fn is_success(&self) -> bool {
268 matches!(
269 self,
270 Self::SuccessMaximumQos0 | Self::SuccessMaximumQos1 | Self::SuccessMaximumQos2
271 )
272 }
273 pub fn is_failure(&self) -> bool {
274 !self.is_success()
275 }
276}
277
278impl fmt::Display for SubackReturnCode {
279 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
280 let s = match self {
281 Self::SuccessMaximumQos0 => "SuccessMaximumQos0",
282 Self::SuccessMaximumQos1 => "SuccessMaximumQos1",
283 Self::SuccessMaximumQos2 => "SuccessMaximumQos2",
284 Self::Failure => "Failure",
285 };
286 write!(f, "{s}")
287 }
288}
289
290impl Serialize for SubackReturnCode {
291 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
292 where
293 S: Serializer,
294 {
295 serializer.serialize_str(&self.to_string())
296 }
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
301#[repr(u8)]
302pub enum ConnectReasonCode {
303 Success = 0x00, UnspecifiedError = 0x80, MalformedPacket = 0x81, ProtocolError = 0x82, ImplementationSpecificError = 0x83, UnsupportedProtocolVersion = 0x84, ClientIdentifierNotValid = 0x85, BadUserNameOrPassword = 0x86, NotAuthorized = 0x87, ServerUnavailable = 0x88, ServerBusy = 0x89, Banned = 0x8a, BadAuthenticationMethod = 0x8c, TopicNameInvalid = 0x90, PacketTooLarge = 0x95, QuotaExceeded = 0x97, PayloadFormatInvalid = 0x99, RetainNotSupported = 0x9a, QosNotSupported = 0x9b, UseAnotherServer = 0x9c, ServerMoved = 0x9d, ConnectionRateExceeded = 0x9f, }
326
327impl fmt::Display for ConnectReasonCode {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 let s = match self {
330 Self::Success => "Success",
331 Self::UnspecifiedError => "UnspecifiedError",
332 Self::MalformedPacket => "MalformedPacket",
333 Self::ProtocolError => "ProtocolError",
334 Self::ImplementationSpecificError => "ImplementationSpecificError",
335 Self::UnsupportedProtocolVersion => "UnsupportedProtocolVersion",
336 Self::ClientIdentifierNotValid => "ClientIdentifierNotValid",
337 Self::BadUserNameOrPassword => "BadUserNameOrPassword",
338 Self::NotAuthorized => "NotAuthorized",
339 Self::ServerUnavailable => "ServerUnavailable",
340 Self::ServerBusy => "ServerBusy",
341 Self::Banned => "Banned",
342 Self::BadAuthenticationMethod => "BadAuthenticationMethod",
343 Self::TopicNameInvalid => "TopicNameInvalid",
344 Self::PacketTooLarge => "PacketTooLarge",
345 Self::QuotaExceeded => "QuotaExceeded",
346 Self::PayloadFormatInvalid => "PayloadFormatInvalid",
347 Self::RetainNotSupported => "RetainNotSupported",
348 Self::QosNotSupported => "QosNotSupported",
349 Self::UseAnotherServer => "UseAnotherServer",
350 Self::ServerMoved => "ServerMoved",
351 Self::ConnectionRateExceeded => "ConnectionRateExceeded",
352 };
353 write!(f, "{s}")
354 }
355}
356
357impl Serialize for ConnectReasonCode {
358 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
359 where
360 S: Serializer,
361 {
362 serializer.serialize_str(&self.to_string())
363 }
364}
365
366impl From<ConnectReasonCode> for MqttError {
367 fn from(code: ConnectReasonCode) -> Self {
368 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
370 }
371}
372
373#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
374#[repr(u8)]
375pub enum DisconnectReasonCode {
376 NormalDisconnection = 0x00,
377 DisconnectWithWillMessage = 0x04,
378 UnspecifiedError = 0x80,
379 MalformedPacket = 0x81,
380 ProtocolError = 0x82,
381 ImplementationSpecificError = 0x83,
382 NotAuthorized = 0x87,
383 ServerBusy = 0x89,
384 ServerShuttingDown = 0x8b,
385 KeepAliveTimeout = 0x8d,
386 SessionTakenOver = 0x8e,
387 TopicFilterInvalid = 0x8f,
388 TopicNameInvalid = 0x90,
389 ReceiveMaximumExceeded = 0x93,
390 TopicAliasInvalid = 0x94,
391 PacketTooLarge = 0x95,
392 MessageRateTooHigh = 0x96,
393 QuotaExceeded = 0x97,
394 AdministrativeAction = 0x98,
395 PayloadFormatInvalid = 0x99,
396 RetainNotSupported = 0x9a,
397 QosNotSupported = 0x9b,
398 UseAnotherServer = 0x9c,
399 ServerMoved = 0x9d,
400 SharedSubscriptionsNotSupported = 0x9e,
401 ConnectionRateExceeded = 0x9f,
402 MaximumConnectTime = 0xa0,
403 SubscriptionIdentifiersNotSupported = 0xa1,
404 WildcardSubscriptionsNotSupported = 0xa2,
405}
406
407impl std::fmt::Display for DisconnectReasonCode {
408 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
409 let s = match self {
410 Self::NormalDisconnection => "NormalDisconnection",
411 Self::DisconnectWithWillMessage => "DisconnectWithWillMessage",
412 Self::UnspecifiedError => "UnspecifiedError",
413 Self::MalformedPacket => "MalformedPacket",
414 Self::ProtocolError => "ProtocolError",
415 Self::ImplementationSpecificError => "ImplementationSpecificError",
416 Self::NotAuthorized => "NotAuthorized",
417 Self::ServerBusy => "ServerBusy",
418 Self::ServerShuttingDown => "ServerShuttingDown",
419 Self::KeepAliveTimeout => "KeepAliveTimeout",
420 Self::SessionTakenOver => "SessionTakenOver",
421 Self::TopicFilterInvalid => "TopicFilterInvalid",
422 Self::TopicNameInvalid => "TopicNameInvalid",
423 Self::ReceiveMaximumExceeded => "ReceiveMaximumExceeded",
424 Self::TopicAliasInvalid => "TopicAliasInvalid",
425 Self::PacketTooLarge => "PacketTooLarge",
426 Self::MessageRateTooHigh => "MessageRateTooHigh",
427 Self::QuotaExceeded => "QuotaExceeded",
428 Self::AdministrativeAction => "AdministrativeAction",
429 Self::PayloadFormatInvalid => "PayloadFormatInvalid",
430 Self::RetainNotSupported => "RetainNotSupported",
431 Self::QosNotSupported => "QosNotSupported",
432 Self::UseAnotherServer => "UseAnotherServer",
433 Self::ServerMoved => "ServerMoved",
434 Self::SharedSubscriptionsNotSupported => "SharedSubscriptionsNotSupported",
435 Self::ConnectionRateExceeded => "ConnectionRateExceeded",
436 Self::MaximumConnectTime => "MaximumConnectTime",
437 Self::SubscriptionIdentifiersNotSupported => "SubscriptionIdentifiersNotSupported",
438 Self::WildcardSubscriptionsNotSupported => "WildcardSubscriptionsNotSupported",
439 };
440 write!(f, "{s}")
441 }
442}
443
444impl Serialize for DisconnectReasonCode {
445 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
446 where
447 S: Serializer,
448 {
449 serializer.serialize_str(&self.to_string())
450 }
451}
452
453impl From<DisconnectReasonCode> for MqttError {
454 fn from(code: DisconnectReasonCode) -> Self {
455 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
457 }
458}
459
460impl From<MqttError> for DisconnectReasonCode {
461 fn from(error: MqttError) -> Self {
462 match error {
463 MqttError::UnspecifiedError => DisconnectReasonCode::UnspecifiedError,
464 MqttError::MalformedPacket => DisconnectReasonCode::MalformedPacket,
465 MqttError::ProtocolError => DisconnectReasonCode::ProtocolError,
466 MqttError::ImplementationSpecificError => {
467 DisconnectReasonCode::ImplementationSpecificError
468 }
469 MqttError::NotAuthorized => DisconnectReasonCode::NotAuthorized,
470 MqttError::ServerBusy => DisconnectReasonCode::ServerBusy,
471 MqttError::ServerShuttingDown => DisconnectReasonCode::ServerShuttingDown,
472 MqttError::KeepAliveTimeout => DisconnectReasonCode::KeepAliveTimeout,
473 MqttError::SessionTakenOver => DisconnectReasonCode::SessionTakenOver,
474 MqttError::TopicFilterInvalid => DisconnectReasonCode::TopicFilterInvalid,
475 MqttError::TopicNameInvalid => DisconnectReasonCode::TopicNameInvalid,
476 MqttError::ReceiveMaximumExceeded => DisconnectReasonCode::ReceiveMaximumExceeded,
477 MqttError::TopicAliasInvalid => DisconnectReasonCode::TopicAliasInvalid,
478 MqttError::PacketTooLarge => DisconnectReasonCode::PacketTooLarge,
479 MqttError::MessageRateTooHigh => DisconnectReasonCode::MessageRateTooHigh,
480 MqttError::QuotaExceeded => DisconnectReasonCode::QuotaExceeded,
481 MqttError::AdministrativeAction => DisconnectReasonCode::AdministrativeAction,
482 MqttError::PayloadFormatInvalid => DisconnectReasonCode::PayloadFormatInvalid,
483 MqttError::RetainNotSupported => DisconnectReasonCode::RetainNotSupported,
484 MqttError::QosNotSupported => DisconnectReasonCode::QosNotSupported,
485 MqttError::UseAnotherServer => DisconnectReasonCode::UseAnotherServer,
486 MqttError::ServerMoved => DisconnectReasonCode::ServerMoved,
487 MqttError::SharedSubscriptionsNotSupported => {
488 DisconnectReasonCode::SharedSubscriptionsNotSupported
489 }
490 MqttError::ConnectionRateExceeded => DisconnectReasonCode::ConnectionRateExceeded,
491 MqttError::MaximumConnectTime => DisconnectReasonCode::MaximumConnectTime,
492 MqttError::SubscriptionIdentifiersNotSupported => {
493 DisconnectReasonCode::SubscriptionIdentifiersNotSupported
494 }
495 MqttError::WildcardSubscriptionsNotSupported => {
496 DisconnectReasonCode::WildcardSubscriptionsNotSupported
497 }
498 _ => DisconnectReasonCode::UnspecifiedError,
500 }
501 }
502}
503
504#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
505#[repr(u8)]
506pub enum SubackReasonCode {
507 GrantedQos0 = 0x00,
508 GrantedQos1 = 0x01,
509 GrantedQos2 = 0x02,
510 UnspecifiedError = 0x80,
511 ImplementationSpecificError = 0x83,
512 NotAuthorized = 0x87,
513 TopicFilterInvalid = 0x8f,
514 PacketIdentifierInUse = 0x91,
515 QuotaExceeded = 0x97,
516 SharedSubscriptionsNotSupported = 0x9e,
517 SubscriptionIdentifiersNotSupported = 0xa1,
518 WildcardSubscriptionsNotSupported = 0xa2,
519}
520
521impl SubackReasonCode {
522 pub fn is_success(&self) -> bool {
523 matches!(
524 self,
525 Self::GrantedQos0 | Self::GrantedQos1 | Self::GrantedQos2
526 )
527 }
528 pub fn is_failure(&self) -> bool {
529 !self.is_success()
530 }
531}
532
533impl std::fmt::Display for SubackReasonCode {
534 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
535 let s = match self {
536 Self::GrantedQos0 => "GrantedQos0",
537 Self::GrantedQos1 => "GrantedQos1",
538 Self::GrantedQos2 => "GrantedQos2",
539 Self::UnspecifiedError => "UnspecifiedError",
540 Self::ImplementationSpecificError => "ImplementationSpecificError",
541 Self::NotAuthorized => "NotAuthorized",
542 Self::TopicFilterInvalid => "TopicFilterInvalid",
543 Self::PacketIdentifierInUse => "PacketIdentifierInUse",
544 Self::QuotaExceeded => "QuotaExceeded",
545 Self::SharedSubscriptionsNotSupported => "SharedSubscriptionsNotSupported",
546 Self::SubscriptionIdentifiersNotSupported => "SubscriptionIdentifiersNotSupported",
547 Self::WildcardSubscriptionsNotSupported => "WildcardSubscriptionsNotSupported",
548 };
549 write!(f, "{s}")
550 }
551}
552
553impl Serialize for SubackReasonCode {
554 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
555 where
556 S: Serializer,
557 {
558 serializer.serialize_str(&self.to_string())
559 }
560}
561
562impl From<SubackReasonCode> for MqttError {
563 fn from(code: SubackReasonCode) -> Self {
564 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
566 }
567}
568
569#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
570#[repr(u8)]
571pub enum UnsubackReasonCode {
572 Success = 0x00,
573 NoSubscriptionExisted = 0x11,
574 UnspecifiedError = 0x80,
575 ImplementationSpecificError = 0x83,
576 NotAuthorized = 0x87,
577 TopicFilterInvalid = 0x8f,
578 PacketIdentifierInUse = 0x91,
579}
580
581impl UnsubackReasonCode {
582 pub fn is_success(&self) -> bool {
583 matches!(self, Self::Success | Self::NoSubscriptionExisted)
584 }
585 pub fn is_failure(&self) -> bool {
586 !self.is_success()
587 }
588}
589
590impl std::fmt::Display for UnsubackReasonCode {
591 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
592 let s = match self {
593 Self::Success => "Success",
594 Self::NoSubscriptionExisted => "NoSubscriptionExisted",
595 Self::UnspecifiedError => "UnspecifiedError",
596 Self::ImplementationSpecificError => "ImplementationSpecificError",
597 Self::NotAuthorized => "NotAuthorized",
598 Self::TopicFilterInvalid => "TopicFilterInvalid",
599 Self::PacketIdentifierInUse => "PacketIdentifierInUse",
600 };
601 write!(f, "{s}")
602 }
603}
604
605impl Serialize for UnsubackReasonCode {
606 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
607 where
608 S: Serializer,
609 {
610 serializer.serialize_str(&self.to_string())
611 }
612}
613
614impl From<UnsubackReasonCode> for MqttError {
615 fn from(code: UnsubackReasonCode) -> Self {
616 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
618 }
619}
620
621#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
622#[repr(u8)]
623pub enum PubackReasonCode {
624 Success = 0x00,
625 NoMatchingSubscribers = 0x10,
626 UnspecifiedError = 0x80,
627 ImplementationSpecificError = 0x83,
628 NotAuthorized = 0x87,
629 TopicNameInvalid = 0x90,
630 PacketIdentifierInUse = 0x91,
631 QuotaExceeded = 0x97,
632 PayloadFormatInvalid = 0x99,
633}
634
635impl PubackReasonCode {
636 pub fn is_success(&self) -> bool {
637 matches!(self, Self::Success | Self::NoMatchingSubscribers)
638 }
639 pub fn is_failure(&self) -> bool {
640 !self.is_success()
641 }
642}
643
644impl std::fmt::Display for PubackReasonCode {
645 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
646 let s = match self {
647 Self::Success => "Success",
648 Self::NoMatchingSubscribers => "NoMatchingSubscribers",
649 Self::UnspecifiedError => "UnspecifiedError",
650 Self::ImplementationSpecificError => "ImplementationSpecificError",
651 Self::NotAuthorized => "NotAuthorized",
652 Self::TopicNameInvalid => "TopicNameInvalid",
653 Self::PacketIdentifierInUse => "PacketIdentifierInUse",
654 Self::QuotaExceeded => "QuotaExceeded",
655 Self::PayloadFormatInvalid => "PayloadFormatInvalid",
656 };
657 write!(f, "{s}")
658 }
659}
660
661impl Serialize for PubackReasonCode {
662 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
663 where
664 S: Serializer,
665 {
666 serializer.serialize_str(&self.to_string())
667 }
668}
669
670impl From<PubackReasonCode> for MqttError {
671 fn from(code: PubackReasonCode) -> Self {
672 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
674 }
675}
676
677#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
678#[repr(u8)]
679pub enum PubrecReasonCode {
680 Success = 0x00,
681 NoMatchingSubscribers = 0x10,
682 UnspecifiedError = 0x80,
683 ImplementationSpecificError = 0x83,
684 NotAuthorized = 0x87,
685 TopicNameInvalid = 0x90,
686 PacketIdentifierInUse = 0x91,
687 QuotaExceeded = 0x97,
688 PayloadFormatInvalid = 0x99,
689}
690
691impl PubrecReasonCode {
692 pub fn is_success(&self) -> bool {
693 matches!(self, Self::Success | Self::NoMatchingSubscribers)
694 }
695 pub fn is_failure(&self) -> bool {
696 !self.is_success()
697 }
698}
699impl std::fmt::Display for PubrecReasonCode {
700 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
701 let s = match self {
702 Self::Success => "Success",
703 Self::NoMatchingSubscribers => "NoMatchingSubscribers",
704 Self::UnspecifiedError => "UnspecifiedError",
705 Self::ImplementationSpecificError => "ImplementationSpecificError",
706 Self::NotAuthorized => "NotAuthorized",
707 Self::TopicNameInvalid => "TopicNameInvalid",
708 Self::PacketIdentifierInUse => "PacketIdentifierInUse",
709 Self::QuotaExceeded => "QuotaExceeded",
710 Self::PayloadFormatInvalid => "PayloadFormatInvalid",
711 };
712 write!(f, "{s}")
713 }
714}
715
716impl Serialize for PubrecReasonCode {
717 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
718 where
719 S: Serializer,
720 {
721 serializer.serialize_str(&self.to_string())
722 }
723}
724
725impl From<PubrecReasonCode> for MqttError {
726 fn from(code: PubrecReasonCode) -> Self {
727 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
729 }
730}
731
732#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
733#[repr(u8)]
734pub enum PubrelReasonCode {
735 Success = 0x00,
736 PacketIdentifierNotFound = 0x92,
737}
738
739impl PubrelReasonCode {
740 pub fn is_success(&self) -> bool {
741 matches!(self, Self::Success)
742 }
743 pub fn is_failure(&self) -> bool {
744 !self.is_success()
745 }
746}
747
748impl std::fmt::Display for PubrelReasonCode {
749 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
750 let s = match self {
751 Self::Success => "Success",
752 Self::PacketIdentifierNotFound => "PacketIdentifierNotFound",
753 };
754 write!(f, "{s}")
755 }
756}
757
758impl Serialize for PubrelReasonCode {
759 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
760 where
761 S: Serializer,
762 {
763 serializer.serialize_str(&self.to_string())
764 }
765}
766
767impl From<PubrelReasonCode> for MqttError {
768 fn from(code: PubrelReasonCode) -> Self {
769 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
771 }
772}
773
774#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
775#[repr(u8)]
776pub enum PubcompReasonCode {
777 Success = 0x00,
778 PacketIdentifierNotFound = 0x92,
779}
780
781impl PubcompReasonCode {
782 pub fn is_success(&self) -> bool {
783 matches!(self, Self::Success)
784 }
785 pub fn is_failure(&self) -> bool {
786 !self.is_success()
787 }
788}
789
790impl std::fmt::Display for PubcompReasonCode {
791 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
792 let s = match self {
793 Self::Success => "Success",
794 Self::PacketIdentifierNotFound => "PacketIdentifierNotFound",
795 };
796 write!(f, "{s}")
797 }
798}
799
800impl Serialize for PubcompReasonCode {
801 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
802 where
803 S: Serializer,
804 {
805 serializer.serialize_str(&self.to_string())
806 }
807}
808
809impl From<PubcompReasonCode> for MqttError {
810 fn from(code: PubcompReasonCode) -> Self {
811 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
813 }
814}
815
816#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
817#[repr(u8)]
818pub enum AuthReasonCode {
819 Success = 0x00,
820 ContinueAuthentication = 0x18,
821 ReAuthenticate = 0x19,
822}
823
824impl AuthReasonCode {
825 pub fn is_success(&self) -> bool {
826 matches!(
827 self,
828 Self::Success | Self::ContinueAuthentication | Self::ReAuthenticate
829 )
830 }
831 pub fn is_failure(&self) -> bool {
832 !self.is_success()
833 }
834}
835
836impl std::fmt::Display for AuthReasonCode {
837 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
838 let s = match self {
839 Self::Success => "Success",
840 Self::ContinueAuthentication => "ContinueAuthentication",
841 Self::ReAuthenticate => "ReAuthenticate",
842 };
843 write!(f, "{s}")
844 }
845}
846
847impl Serialize for AuthReasonCode {
848 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
849 where
850 S: Serializer,
851 {
852 serializer.serialize_str(&self.to_string())
853 }
854}
855
856impl From<AuthReasonCode> for MqttError {
857 fn from(code: AuthReasonCode) -> Self {
858 MqttError::try_from(code as u8).unwrap_or(MqttError::ProtocolError)
860 }
861}