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