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