mqtt_proto/common/
error.rs

1use std::io;
2
3use thiserror::Error;
4
5use crate::Protocol;
6
7/// Errors returned by encoding and decoding process.
8#[derive(Error, Debug, Clone, PartialEq, Eq)]
9pub enum Error {
10    /// Invalid remaining length.
11    #[error("invalid remaining length")]
12    InvalidRemainingLength,
13
14    /// No subscription in subscribe packet.
15    #[error("empty subscription")]
16    EmptySubscription,
17
18    /// Packet identifier is 0.
19    #[error("packet identifier is 0")]
20    ZeroPid,
21
22    /// Invalid QoS value.
23    #[error("invalid qos: `{0}`")]
24    InvalidQos(u8),
25
26    /// Invalid connect flags.
27    #[error("invalid connect flags: `{0}`")]
28    InvalidConnectFlags(u8),
29
30    /// Invalid connack flags (not 0 or 1).
31    #[error("invalid connack flags: `{0}`")]
32    InvalidConnackFlags(u8),
33
34    /// Invalid connect return code (value > 5).
35    #[error("invalid connect return code: `{0}`")]
36    InvalidConnectReturnCode(u8),
37
38    /// Invalid protocol.
39    #[error("invalid protocol: {0}, {1}")]
40    InvalidProtocol(String, u8),
41
42    /// Unexpected protocol
43    #[error("unexpected protocol version: `{0}`")]
44    UnexpectedProtocol(Protocol),
45
46    /// Invalid fixed header (packet type, flags, or remaining_length).
47    #[error("invalid header")]
48    InvalidHeader,
49
50    /// Invalid variable byte integer, the value MUST smaller than `268,435,456`.
51    #[error("invalid variable byte integer")]
52    InvalidVarByteInt,
53
54    /// Invalid Topic Name
55    #[error("invalid topic name: {0}")]
56    InvalidTopicName(String),
57
58    /// Invalid topic filter
59    #[error("invalid topic filter: {0}")]
60    InvalidTopicFilter(String),
61
62    /// Trying to decode a non-utf8 string.
63    #[error("invalid string")]
64    InvalidString,
65
66    /// Catch-all error when converting from `std::io::Error`.
67    #[error("io error: {0}, {1}")]
68    IoError(io::ErrorKind, String),
69}
70
71impl Error {
72    pub fn is_eof(&self) -> bool {
73        matches!(self, Error::IoError(kind, _) if *kind == io::ErrorKind::UnexpectedEof)
74    }
75}
76
77impl From<io::Error> for Error {
78    fn from(err: io::Error) -> Error {
79        Error::IoError(err.kind(), err.to_string())
80    }
81}
82
83impl From<Error> for io::Error {
84    fn from(err: Error) -> io::Error {
85        match err {
86            Error::IoError(kind, _info) => kind.into(),
87            _ => io::ErrorKind::InvalidData.into(),
88        }
89    }
90}