mqute_codec/protocol/v5/
reason.rs

1//! # MQTT Reason Codes V5
2//!
3//! This module defines the `ReasonCode` enum, which represents all possible reason codes
4//! used in MQTT v5 protocol packets. Reason codes provide detailed information about
5//! the result of operations or the cause of disconnections.
6
7use crate::Error;
8use std::fmt::{Display, Formatter};
9
10/// Represents all possible reason codes in MQTT v5 protocol.
11///
12/// Reason codes are used in various MQTT packets to indicate the result of operations
13/// or the reason for disconnections. Each variant corresponds to a specific numeric code
14/// as defined in the MQTT v5 specification.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum ReasonCode {
17    /// Success (0x00)
18    Success,
19    /// Normal disconnection (0x00)
20    NormalDisconnection,
21    /// Granted QoS 0 (0x00)
22    GrantedQos0,
23    /// Granted QoS 1 (0x01)
24    GrantedQos1,
25    /// Granted QoS 2 (0x02)
26    GrantedQos2,
27    /// Disconnect with Will Message (0x04)
28    DisconnectWithWillMessage,
29    /// No matching subscribers (0x10)
30    NoMatchingSubscribers,
31    /// No subscription existed (0x11)
32    NoSubscriptionExisted,
33    /// Continue authentication (0x18)
34    ContinueAuthentication,
35    /// Re-authenticate (0x19)
36    ReAuthenticate,
37    /// Unspecified error (0x80)
38    UnspecifiedError,
39    /// Malformed Packet (0x81)
40    MalformedPacket,
41    /// Protocol Error (0x82)
42    ProtocolError,
43    /// Implementation specific error (0x83)
44    ImplementationSpecificError,
45    /// Unsupported Protocol Version (0x84)
46    UnsupportedProtocolVersion,
47    /// Client Identifier not valid (0x85)
48    ClientIdentifierNotValid,
49    /// Bad User Name or Password (0x86)
50    BadUserNameOrPassword,
51    /// Not authorized (0x87)
52    NotAuthorized,
53    /// Server unavailable (0x88)
54    ServerUnavailable,
55    /// Server busy (0x89)
56    ServerBusy,
57    /// Banned (0x8A)
58    Banned,
59    /// Server shutting down (0x8B)
60    ServerShuttingDown,
61    /// Bad authentication method (0x8C)
62    BadAuthenticationMethod,
63    /// Keep Alive timeout (0x8D)
64    KeepAliveTimeout,
65    /// Session taken over (0x8E)
66    SessionTakenOver,
67    /// Topic Filter invalid (0x8F)
68    TopicFilterInvalid,
69    /// Topic Name invalid (0x90)
70    TopicNameInvalid,
71    /// Packet Identifier in use (0x91)
72    PacketIdentifierInUse,
73    /// Packet Identifier not found (0x92)
74    PacketIdentifierNotFound,
75    /// Receive Maximum exceeded (0x93)
76    ReceiveMaximumExceeded,
77    /// Topic Alias invalid (0x94)
78    TopicAliasInvalid,
79    /// Packet too large (0x95)
80    PacketTooLarge,
81    /// Message rate too high (0x96)
82    MessageRateTooHigh,
83    /// Quota exceeded (0x97)
84    QuotaExceeded,
85    /// Administrative action (0x98)
86    AdministrativeAction,
87    /// Payload format invalid (0x99)
88    PayloadFormatInvalid,
89    /// Retain not supported (0x9A)
90    RetainNotSupported,
91    /// QoS not supported (0x9B)
92    QosNotSupported,
93    /// Use another server (0x9C)
94    UseAnotherServer,
95    /// Server moved (0x9D)
96    ServerMoved,
97    /// Shared Subscriptions not supported (0x9E)
98    SharedSubscriptionsNotSupported,
99    /// Connection rate exceeded (0x9F)
100    ConnectionRateExceeded,
101    /// Maximum connect time (0xA0)
102    MaximumConnectTime,
103    /// Subscription Identifiers not supported (0xA1)
104    SubscriptionIdentifiersNotSupported,
105    /// Wildcard Subscriptions not supported (0xA2)
106    WildcardSubscriptionsNotSupported,
107}
108
109impl From<ReasonCode> for u8 {
110    /// Converts a `ReasonCode` to its numeric representation.
111    ///
112    /// # Example
113    ///
114    /// ```rust
115    /// use mqute_codec::protocol::v5::ReasonCode;
116    ///
117    /// let code: u8 = ReasonCode::GrantedQos1.into();
118    /// assert_eq!(code, 1);
119    /// ```
120    fn from(value: ReasonCode) -> Self {
121        match value {
122            ReasonCode::Success => 0,
123            ReasonCode::NormalDisconnection => 0,
124            ReasonCode::GrantedQos0 => 0,
125            ReasonCode::GrantedQos1 => 1,
126            ReasonCode::GrantedQos2 => 2,
127            ReasonCode::DisconnectWithWillMessage => 4,
128            ReasonCode::NoMatchingSubscribers => 16,
129            ReasonCode::NoSubscriptionExisted => 17,
130            ReasonCode::ContinueAuthentication => 24,
131            ReasonCode::ReAuthenticate => 25,
132            ReasonCode::UnspecifiedError => 128,
133            ReasonCode::MalformedPacket => 129,
134            ReasonCode::ProtocolError => 130,
135            ReasonCode::ImplementationSpecificError => 131,
136            ReasonCode::UnsupportedProtocolVersion => 132,
137            ReasonCode::ClientIdentifierNotValid => 133,
138            ReasonCode::BadUserNameOrPassword => 134,
139            ReasonCode::NotAuthorized => 135,
140            ReasonCode::ServerUnavailable => 136,
141            ReasonCode::ServerBusy => 137,
142            ReasonCode::Banned => 138,
143            ReasonCode::ServerShuttingDown => 139,
144            ReasonCode::BadAuthenticationMethod => 140,
145            ReasonCode::KeepAliveTimeout => 141,
146            ReasonCode::SessionTakenOver => 142,
147            ReasonCode::TopicFilterInvalid => 143,
148            ReasonCode::TopicNameInvalid => 144,
149            ReasonCode::PacketIdentifierInUse => 145,
150            ReasonCode::PacketIdentifierNotFound => 146,
151            ReasonCode::ReceiveMaximumExceeded => 147,
152            ReasonCode::TopicAliasInvalid => 148,
153            ReasonCode::PacketTooLarge => 149,
154            ReasonCode::MessageRateTooHigh => 150,
155            ReasonCode::QuotaExceeded => 151,
156            ReasonCode::AdministrativeAction => 152,
157            ReasonCode::PayloadFormatInvalid => 153,
158            ReasonCode::RetainNotSupported => 154,
159            ReasonCode::QosNotSupported => 155,
160            ReasonCode::UseAnotherServer => 156,
161            ReasonCode::ServerMoved => 157,
162            ReasonCode::SharedSubscriptionsNotSupported => 158,
163            ReasonCode::ConnectionRateExceeded => 159,
164            ReasonCode::MaximumConnectTime => 160,
165            ReasonCode::SubscriptionIdentifiersNotSupported => 161,
166            ReasonCode::WildcardSubscriptionsNotSupported => 162,
167        }
168    }
169}
170
171impl TryFrom<u8> for ReasonCode {
172    type Error = Error;
173
174    /// Attempts to convert a numeric value to a `ReasonCode`.
175    ///
176    /// # Example
177    ///
178    /// ```rust
179    /// use mqute_codec::protocol::v5::ReasonCode;
180    ///
181    /// let code = ReasonCode::try_from(0x85).unwrap();
182    /// assert_eq!(code, ReasonCode::ClientIdentifierNotValid);
183    /// ```
184    fn try_from(value: u8) -> Result<Self, Self::Error> {
185        let code = match value {
186            0 => Self::Success,
187            1 => Self::GrantedQos1,
188            2 => Self::GrantedQos2,
189            4 => Self::DisconnectWithWillMessage,
190            16 => Self::NoMatchingSubscribers,
191            17 => Self::NoSubscriptionExisted,
192            24 => Self::ContinueAuthentication,
193            25 => Self::ReAuthenticate,
194            128 => Self::UnspecifiedError,
195            129 => Self::MalformedPacket,
196            130 => Self::ProtocolError,
197            131 => Self::ImplementationSpecificError,
198            132 => Self::UnsupportedProtocolVersion,
199            133 => Self::ClientIdentifierNotValid,
200            134 => Self::BadUserNameOrPassword,
201            135 => Self::NotAuthorized,
202            136 => Self::ServerUnavailable,
203            137 => Self::ServerBusy,
204            138 => Self::Banned,
205            139 => Self::ServerShuttingDown,
206            140 => Self::BadAuthenticationMethod,
207            141 => Self::KeepAliveTimeout,
208            142 => Self::SessionTakenOver,
209            143 => Self::TopicFilterInvalid,
210            144 => Self::TopicNameInvalid,
211            145 => Self::PacketIdentifierInUse,
212            146 => Self::PacketIdentifierNotFound,
213            147 => Self::ReceiveMaximumExceeded,
214            148 => Self::TopicAliasInvalid,
215            149 => Self::PacketTooLarge,
216            150 => Self::MessageRateTooHigh,
217            151 => Self::QuotaExceeded,
218            152 => Self::AdministrativeAction,
219            153 => Self::PayloadFormatInvalid,
220            154 => Self::RetainNotSupported,
221            155 => Self::QosNotSupported,
222            156 => Self::UseAnotherServer,
223            157 => Self::ServerMoved,
224            158 => Self::SharedSubscriptionsNotSupported,
225            159 => Self::ConnectionRateExceeded,
226            160 => Self::MaximumConnectTime,
227            161 => Self::SubscriptionIdentifiersNotSupported,
228            162 => Self::WildcardSubscriptionsNotSupported,
229            n => return Err(Error::InvalidReasonCode(n)),
230        };
231
232        Ok(code)
233    }
234}
235
236impl Display for ReasonCode {
237    /// Provides human-readable display for reason codes.
238    ///
239    /// # Example
240    ///
241    /// ```rust
242    /// use mqute_codec::protocol::v5::ReasonCode;
243    /// let str = format!("{}", ReasonCode::ProtocolError);
244    /// let text = "Protocol Error".to_string();
245    /// assert_eq!(text, str);
246    /// ```
247    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
248        match *self {
249            ReasonCode::Success => write!(f, "Success"),
250            ReasonCode::NormalDisconnection => write!(f, "Normal disconnection"),
251            ReasonCode::GrantedQos0 => write!(f, "Granted QoS 0"),
252            ReasonCode::GrantedQos1 => write!(f, "Granted QoS 1"),
253            ReasonCode::GrantedQos2 => write!(f, "Granted QoS 2"),
254            ReasonCode::DisconnectWithWillMessage => write!(f, "Disconnect with Will Message"),
255            ReasonCode::NoMatchingSubscribers => write!(f, "No matching subscribers"),
256            ReasonCode::NoSubscriptionExisted => write!(f, "No subscription existed"),
257            ReasonCode::ContinueAuthentication => write!(f, "Continue authentication"),
258            ReasonCode::ReAuthenticate => write!(f, "Re authenticate"),
259            ReasonCode::UnspecifiedError => write!(f, "Unspecified error"),
260            ReasonCode::MalformedPacket => write!(f, "Malformed Packet"),
261            ReasonCode::ProtocolError => write!(f, "Protocol Error"),
262            ReasonCode::ImplementationSpecificError => write!(f, "Implementation specific error"),
263            ReasonCode::UnsupportedProtocolVersion => write!(f, "Unsupported Protocol Version"),
264            ReasonCode::ClientIdentifierNotValid => write!(f, "Client Identifier not valid"),
265            ReasonCode::BadUserNameOrPassword => write!(f, "Bad User Name or Password"),
266            ReasonCode::NotAuthorized => write!(f, "Not authorized"),
267            ReasonCode::ServerUnavailable => write!(f, "Server unavailable"),
268            ReasonCode::ServerBusy => write!(f, "Server busy"),
269            ReasonCode::Banned => write!(f, "Banned"),
270            ReasonCode::ServerShuttingDown => write!(f, "Server shutting down"),
271            ReasonCode::BadAuthenticationMethod => write!(f, "Bad authentication method"),
272            ReasonCode::KeepAliveTimeout => write!(f, "Keep Alive timeout"),
273            ReasonCode::SessionTakenOver => write!(f, "Session taken over"),
274            ReasonCode::TopicFilterInvalid => write!(f, "Topic Filter invalid"),
275            ReasonCode::TopicNameInvalid => write!(f, "Topic Name invalid"),
276            ReasonCode::PacketIdentifierInUse => write!(f, "Packet Identifier in use"),
277            ReasonCode::PacketIdentifierNotFound => write!(f, "Packet Identifier not found"),
278            ReasonCode::ReceiveMaximumExceeded => write!(f, "Receive Maximum exceeded"),
279            ReasonCode::TopicAliasInvalid => write!(f, "Topic Alias invalid"),
280            ReasonCode::PacketTooLarge => write!(f, "Packet too large"),
281            ReasonCode::MessageRateTooHigh => write!(f, "Message rate too high"),
282            ReasonCode::QuotaExceeded => write!(f, "Quota exceeded"),
283            ReasonCode::AdministrativeAction => write!(f, "Administrative action"),
284            ReasonCode::PayloadFormatInvalid => write!(f, "Payload format invalid"),
285            ReasonCode::RetainNotSupported => write!(f, "Retain not supported"),
286            ReasonCode::QosNotSupported => write!(f, "QoS not supported"),
287            ReasonCode::UseAnotherServer => write!(f, "Use another server"),
288            ReasonCode::ServerMoved => write!(f, "Server moved"),
289            ReasonCode::SharedSubscriptionsNotSupported => {
290                write!(f, "Shared Subscriptions not supported")
291            }
292            ReasonCode::ConnectionRateExceeded => write!(f, "Connection rate exceeded"),
293            ReasonCode::MaximumConnectTime => write!(f, "Maximum connect time"),
294            ReasonCode::SubscriptionIdentifiersNotSupported => {
295                write!(f, "Subscription Identifiers not supported")
296            }
297            ReasonCode::WildcardSubscriptionsNotSupported => {
298                write!(f, "Wildcard Subscriptions not supported")
299            }
300        }
301    }
302}