1use std::io;
11
12use bytestring::ByteString;
13use serde::{Deserialize, Serialize};
14
15use crate::v5::{DisconnectReasonCode, ToReasonCode};
16
17#[derive(Deserialize, Serialize, Debug, Clone, thiserror::Error)]
19pub enum HandshakeError {
20 #[error("Mqtt protocol error: {}", _0)]
22 Protocol(#[from] ProtocolError),
23 #[error("Handshake timeout")]
25 Timeout,
26}
27
28impl ToReasonCode for HandshakeError {
29 fn to_reason_code(&self) -> DisconnectReasonCode {
30 match self {
31 HandshakeError::Protocol(err) => err.to_reason_code(),
32 HandshakeError::Timeout => DisconnectReasonCode::MaximumConnectTime,
33 }
35 }
36}
37
38#[derive(Deserialize, Serialize, Debug, Clone, thiserror::Error)]
40pub enum ProtocolError {
41 #[error("Decoding error: {0:?}")]
43 Decode(#[from] DecodeError),
44 #[error("Encoding error: {0:?}")]
46 Encode(#[from] EncodeError),
47 #[error("Keep Alive timeout")]
49 KeepAliveTimeout,
50}
51
52impl ToReasonCode for ProtocolError {
53 fn to_reason_code(&self) -> DisconnectReasonCode {
54 match self {
55 ProtocolError::Decode(err) => err.to_reason_code(),
56 ProtocolError::Encode(err) => err.to_reason_code(),
57 ProtocolError::KeepAliveTimeout => DisconnectReasonCode::KeepAliveTimeout,
58 }
59 }
60}
61
62#[derive(Debug, Clone, thiserror::Error, Deserialize, Serialize)]
64pub enum DecodeError {
65 #[error("Invalid protocol")]
66 InvalidProtocol,
67 #[error("Invalid length")]
68 InvalidLength,
69 #[error("Malformed packet")]
70 MalformedPacket,
71 #[error("Unsupported protocol level")]
72 UnsupportedProtocolLevel,
73 #[error("Connect frame's reserved flag is set")]
74 ConnectReservedFlagSet,
75 #[error("ConnectAck frame's reserved flag is set")]
76 ConnAckReservedFlagSet,
77 #[error("Invalid client id")]
78 InvalidClientId,
79 #[error("Unsupported packet type")]
80 UnsupportedPacketType,
81 #[error("Packet id is required")]
83 PacketIdRequired,
84 #[error("Max size exceeded: size={size}, max={max}")]
85 MaxSizeExceeded { size: u32, max: u32 },
86 #[error("utf8 error")]
87 Utf8Error,
88 #[error("io error, {:?}", _0)]
89 Io(ByteString),
90}
91
92impl From<io::Error> for DecodeError {
93 fn from(e: io::Error) -> DecodeError {
94 DecodeError::Io(e.to_string().into())
95 }
96}
97
98impl ToReasonCode for DecodeError {
99 fn to_reason_code(&self) -> DisconnectReasonCode {
100 match self {
101 DecodeError::InvalidProtocol => DisconnectReasonCode::ProtocolError,
102 DecodeError::InvalidLength => DisconnectReasonCode::MalformedPacket,
103 DecodeError::MalformedPacket => DisconnectReasonCode::MalformedPacket,
104 DecodeError::UnsupportedProtocolLevel => DisconnectReasonCode::ImplementationSpecificError,
105 DecodeError::ConnectReservedFlagSet => DisconnectReasonCode::ProtocolError,
106 DecodeError::ConnAckReservedFlagSet => DisconnectReasonCode::ProtocolError,
107 DecodeError::InvalidClientId => DisconnectReasonCode::NotAuthorized,
108 DecodeError::UnsupportedPacketType => DisconnectReasonCode::ImplementationSpecificError,
109 DecodeError::PacketIdRequired => DisconnectReasonCode::ProtocolError,
110 DecodeError::MaxSizeExceeded { .. } => DisconnectReasonCode::PacketTooLarge,
111 DecodeError::Utf8Error => DisconnectReasonCode::PayloadFormatInvalid,
112 DecodeError::Io(_) => DisconnectReasonCode::UnspecifiedError,
113 }
114 }
115}
116
117#[derive(Deserialize, Serialize, Debug, Clone, thiserror::Error)]
119pub enum EncodeError {
120 #[error("Packet is bigger than peer's Maximum Packet Size: size={size}, max={max}")]
121 OverMaxPacketSize { size: u32, max: u32 },
122 #[error("Invalid length")]
123 InvalidLength,
124 #[error("Malformed packet")]
125 MalformedPacket,
126 #[error("Packet id is required")]
127 PacketIdRequired,
128 #[error("Unsupported version")]
129 UnsupportedVersion,
130 #[error("io error, {:?}", _0)]
131 Io(ByteString),
132}
133
134impl From<io::Error> for EncodeError {
135 fn from(e: io::Error) -> EncodeError {
136 EncodeError::Io(e.to_string().into())
137 }
138}
139
140impl ToReasonCode for EncodeError {
141 fn to_reason_code(&self) -> DisconnectReasonCode {
142 match self {
143 EncodeError::OverMaxPacketSize { .. } => DisconnectReasonCode::PacketTooLarge,
144 EncodeError::InvalidLength => DisconnectReasonCode::MalformedPacket,
145 EncodeError::MalformedPacket => DisconnectReasonCode::MalformedPacket,
146 EncodeError::PacketIdRequired => DisconnectReasonCode::ProtocolError,
147 EncodeError::UnsupportedVersion => DisconnectReasonCode::ImplementationSpecificError,
148 EncodeError::Io(_) => DisconnectReasonCode::UnspecifiedError,
149 }
150 }
151}
152
153#[derive(Deserialize, Serialize, Debug, Clone, thiserror::Error)]
157pub enum SendPacketError {
158 #[error("Encoding error {:?}", _0)]
160 Encode(#[from] EncodeError),
161 }
169
170impl ToReasonCode for SendPacketError {
171 fn to_reason_code(&self) -> DisconnectReasonCode {
172 match self {
173 SendPacketError::Encode(e) => e.to_reason_code(),
174 }
175 }
176}