1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
use core::{
    convert::From,
    fmt,
    str::Utf8Error,
};

use crate::qos;

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum DecodeError {
    /// Invalid packet type in header
    PacketType,
    /// Invalid packet type flag in header
    PacketFlag,
    /// Malformed remaining length in header
    RemainingLength,
    /// Invalid buffer length
    InvalidLength,
    /// Invalid UTF-8 encoding
    Utf8,
    /// Invalid QoS value
    InvalidQoS(qos::Error),
    /// Invalid protocol level
    InvalidProtocolLevel,
    /// Invalid connect flag value
    InvalidConnectFlag,
    /// Invalid Connack flag
    InvalidConnackFlag,
    /// Invalid Connack Return Code
    InvalidConnackReturnCode,
    /// Invalid Suback Return Code
    InvalidSubackReturnCode,
}

impl DecodeError {
    fn desc(&self) -> &'static str {
        match *self {
            DecodeError::PacketType => "invalid packet type in header",
            DecodeError::PacketFlag => "invalid packet type flag in header",
            DecodeError::RemainingLength => "malformed remaining length in header",
            DecodeError::InvalidLength => "invalid buffer length",
            DecodeError::Utf8 => "invalid utf-8 encoding",
            DecodeError::InvalidQoS(_) => "invalid QoS bit pattern",
            DecodeError::InvalidProtocolLevel => "invalid protocol level",
            DecodeError::InvalidConnectFlag => "invalid connect flag value",
            DecodeError::InvalidConnackFlag => "invalid connack flag value",
            DecodeError::InvalidConnackReturnCode => "invalid connack return code",
            DecodeError::InvalidSubackReturnCode => "invalid suback return code",
        }
    }
}

impl fmt::Display for DecodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.desc())
    }
}

#[cfg(feature = "std")]
impl ::std::error::Error for DecodeError {
    fn description(&self) -> &str {
        self.desc()
    }
}

impl From<Utf8Error> for DecodeError {
    fn from(_: Utf8Error) -> Self {
        DecodeError::Utf8
    }
}

impl From<qos::Error> for DecodeError {
    fn from(err: qos::Error) -> Self {
        DecodeError::InvalidQoS(err)
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum EncodeError {
    /// Not enough space in buffer to encode
    OutOfSpace,
    /// Value too big for field
    ValueTooBig,
}

impl EncodeError {
    fn desc(&self) -> &'static str {
        match *self {
            EncodeError::OutOfSpace => "not enough space in encode buffer",
            EncodeError::ValueTooBig => "value too big to ever be encoded"
        }
    }
}

impl fmt::Display for EncodeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.desc())
    }
}

#[cfg(feature = "std")]
impl ::std::error::Error for EncodeError {
    fn description(&self) -> &str {
        self.desc()
    }
}

impl From<core::num::TryFromIntError> for EncodeError {
    fn from(_err: core::num::TryFromIntError) -> EncodeError {
        EncodeError::ValueTooBig
    }
}