mqtt5_protocol/protocol/v5/
reason_codes.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum ReasonCode {
3 Success = 0x00, GrantedQoS1 = 0x01,
6 GrantedQoS2 = 0x02,
7 DisconnectWithWillMessage = 0x04,
8 NoMatchingSubscribers = 0x10,
9 NoSubscriptionExisted = 0x11,
10 ContinueAuthentication = 0x18,
11 ReAuthenticate = 0x19,
12
13 UnspecifiedError = 0x80,
15 MalformedPacket = 0x81,
16 ProtocolError = 0x82,
17 ImplementationSpecificError = 0x83,
18 UnsupportedProtocolVersion = 0x84,
19 ClientIdentifierNotValid = 0x85,
20 BadUsernameOrPassword = 0x86,
21 NotAuthorized = 0x87,
22 ServerUnavailable = 0x88,
23 ServerBusy = 0x89,
24 Banned = 0x8A,
25 ServerShuttingDown = 0x8B,
26 BadAuthenticationMethod = 0x8C,
27 KeepAliveTimeout = 0x8D,
28 SessionTakenOver = 0x8E,
29 TopicFilterInvalid = 0x8F,
30 TopicNameInvalid = 0x90,
31 PacketIdentifierInUse = 0x91,
32 PacketIdentifierNotFound = 0x92,
33 ReceiveMaximumExceeded = 0x93,
34 TopicAliasInvalid = 0x94,
35 PacketTooLarge = 0x95,
36 MessageRateTooHigh = 0x96,
37 QuotaExceeded = 0x97,
38 AdministrativeAction = 0x98,
39 PayloadFormatInvalid = 0x99,
40 RetainNotSupported = 0x9A,
41 QoSNotSupported = 0x9B,
42 UseAnotherServer = 0x9C,
43 ServerMoved = 0x9D,
44 SharedSubscriptionsNotSupported = 0x9E,
45 ConnectionRateExceeded = 0x9F,
46 MaximumConnectTime = 0xA0,
47 SubscriptionIdentifiersNotSupported = 0xA1,
48 WildcardSubscriptionsNotSupported = 0xA2,
49}
50
51pub const NORMAL_DISCONNECTION: ReasonCode = ReasonCode::Success;
53pub const GRANTED_QOS_0: ReasonCode = ReasonCode::Success;
54
55impl From<ReasonCode> for u8 {
56 fn from(code: ReasonCode) -> Self {
57 code as u8
58 }
59}
60
61impl ReasonCode {
62 #[must_use]
63 pub fn is_success(&self) -> bool {
64 u8::from(*self) < 0x80
65 }
66
67 #[must_use]
68 pub fn is_error(&self) -> bool {
69 u8::from(*self) >= 0x80
70 }
71
72 #[must_use]
73 pub fn from_u8(value: u8) -> Option<Self> {
74 match value {
75 0x00 => Some(Self::Success),
76 0x01 => Some(Self::GrantedQoS1),
77 0x02 => Some(Self::GrantedQoS2),
78 0x04 => Some(Self::DisconnectWithWillMessage),
79 0x10 => Some(Self::NoMatchingSubscribers),
80 0x11 => Some(Self::NoSubscriptionExisted),
81 0x18 => Some(Self::ContinueAuthentication),
82 0x19 => Some(Self::ReAuthenticate),
83 0x80 => Some(Self::UnspecifiedError),
84 0x81 => Some(Self::MalformedPacket),
85 0x82 => Some(Self::ProtocolError),
86 0x83 => Some(Self::ImplementationSpecificError),
87 0x84 => Some(Self::UnsupportedProtocolVersion),
88 0x85 => Some(Self::ClientIdentifierNotValid),
89 0x86 => Some(Self::BadUsernameOrPassword),
90 0x87 => Some(Self::NotAuthorized),
91 0x88 => Some(Self::ServerUnavailable),
92 0x89 => Some(Self::ServerBusy),
93 0x8A => Some(Self::Banned),
94 0x8B => Some(Self::ServerShuttingDown),
95 0x8C => Some(Self::BadAuthenticationMethod),
96 0x8D => Some(Self::KeepAliveTimeout),
97 0x8E => Some(Self::SessionTakenOver),
98 0x8F => Some(Self::TopicFilterInvalid),
99 0x90 => Some(Self::TopicNameInvalid),
100 0x91 => Some(Self::PacketIdentifierInUse),
101 0x92 => Some(Self::PacketIdentifierNotFound),
102 0x93 => Some(Self::ReceiveMaximumExceeded),
103 0x94 => Some(Self::TopicAliasInvalid),
104 0x95 => Some(Self::PacketTooLarge),
105 0x96 => Some(Self::MessageRateTooHigh),
106 0x97 => Some(Self::QuotaExceeded),
107 0x98 => Some(Self::AdministrativeAction),
108 0x99 => Some(Self::PayloadFormatInvalid),
109 0x9A => Some(Self::RetainNotSupported),
110 0x9B => Some(Self::QoSNotSupported),
111 0x9C => Some(Self::UseAnotherServer),
112 0x9D => Some(Self::ServerMoved),
113 0x9E => Some(Self::SharedSubscriptionsNotSupported),
114 0x9F => Some(Self::ConnectionRateExceeded),
115 0xA0 => Some(Self::MaximumConnectTime),
116 0xA1 => Some(Self::SubscriptionIdentifiersNotSupported),
117 0xA2 => Some(Self::WildcardSubscriptionsNotSupported),
118 _ => None,
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_reason_code_success_check() {
129 assert!(ReasonCode::Success.is_success());
130 assert!(ReasonCode::GrantedQoS1.is_success());
131 assert!(ReasonCode::GrantedQoS2.is_success());
132 assert!(ReasonCode::NoMatchingSubscribers.is_success());
133
134 assert!(!ReasonCode::UnspecifiedError.is_success());
135 assert!(!ReasonCode::MalformedPacket.is_success());
136 assert!(!ReasonCode::NotAuthorized.is_success());
137 }
138
139 #[test]
140 fn test_reason_code_error_check() {
141 assert!(!ReasonCode::Success.is_error());
142 assert!(!ReasonCode::GrantedQoS1.is_error());
143
144 assert!(ReasonCode::UnspecifiedError.is_error());
145 assert!(ReasonCode::MalformedPacket.is_error());
146 assert!(ReasonCode::ProtocolError.is_error());
147 assert!(ReasonCode::ServerBusy.is_error());
148 }
149
150 #[test]
151 fn test_reason_code_from_u8() {
152 assert_eq!(ReasonCode::from_u8(0x00), Some(ReasonCode::Success));
153 assert_eq!(ReasonCode::from_u8(0x01), Some(ReasonCode::GrantedQoS1));
154 assert_eq!(ReasonCode::from_u8(0x02), Some(ReasonCode::GrantedQoS2));
155 assert_eq!(
156 ReasonCode::from_u8(0x80),
157 Some(ReasonCode::UnspecifiedError)
158 );
159 assert_eq!(ReasonCode::from_u8(0x81), Some(ReasonCode::MalformedPacket));
160 assert_eq!(ReasonCode::from_u8(0x87), Some(ReasonCode::NotAuthorized));
161 assert_eq!(
162 ReasonCode::from_u8(0xA2),
163 Some(ReasonCode::WildcardSubscriptionsNotSupported)
164 );
165
166 assert_eq!(ReasonCode::from_u8(0x03), None);
168 assert_eq!(ReasonCode::from_u8(0x05), None);
169 assert_eq!(ReasonCode::from_u8(0xFF), None);
170 }
171
172 #[test]
173 fn test_reason_code_aliases() {
174 assert_eq!(NORMAL_DISCONNECTION, ReasonCode::Success);
175 assert_eq!(GRANTED_QOS_0, ReasonCode::Success);
176 assert_eq!(NORMAL_DISCONNECTION as u8, 0x00);
177 assert_eq!(GRANTED_QOS_0 as u8, 0x00);
178 }
179
180 #[test]
181 fn test_reason_code_values() {
182 assert_eq!(ReasonCode::Success as u8, 0x00);
184 assert_eq!(ReasonCode::DisconnectWithWillMessage as u8, 0x04);
185 assert_eq!(ReasonCode::NoMatchingSubscribers as u8, 0x10);
186 assert_eq!(ReasonCode::UnspecifiedError as u8, 0x80);
187 assert_eq!(ReasonCode::ClientIdentifierNotValid as u8, 0x85);
188 assert_eq!(ReasonCode::ServerBusy as u8, 0x89);
189 assert_eq!(ReasonCode::QuotaExceeded as u8, 0x97);
190 assert_eq!(ReasonCode::WildcardSubscriptionsNotSupported as u8, 0xA2);
191 }
192}