async_pop2/
error.rs

1use std::{
2    error,
3    fmt::{self},
4    num::ParseIntError,
5    result,
6    str::Utf8Error,
7};
8
9use crate::runtime::io::Error as IoError;
10
11macro_rules! err {
12    ($kind:expr, $($arg:tt)*) => {{
13		use crate::error::Error;
14
15        let kind = $kind;
16        let message = format!($($arg)*);
17        return Err(Error::new( kind, message ));
18    }};
19}
20
21#[derive(Debug)]
22pub enum ErrorKind {
23    #[cfg(feature = "async-native-tls")]
24    Tls(async_native_tls::Error),
25    #[cfg(feature = "async-rustls")]
26    InvalidDnsName,
27    Io(IoError),
28    ParseInt(ParseIntError),
29    ParseString(Utf8Error),
30    ServerError(String),
31    #[cfg(feature = "sasl")]
32    DecodeBase64(base64::DecodeError),
33    NotConnected,
34    ShouldNotBeConnected,
35    IncorrectStateForCommand,
36    MessageIsDeleted,
37    FeatureUnsupported,
38    ServerFailedToGreet,
39    InvalidResponse,
40    ResponseTooLarge,
41    MissingRequest,
42    ParseCommand,
43    UnexpectedResponse,
44    ConnectionClosed,
45}
46
47#[derive(Debug)]
48pub struct Error {
49    message: String,
50    kind: ErrorKind,
51}
52
53impl Error {
54    pub fn new<S>(error_kind: ErrorKind, message: S) -> Self
55    where
56        String: From<S>,
57    {
58        Self {
59            message: message.into(),
60            kind: error_kind,
61        }
62    }
63
64    pub fn message(&self) -> &str {
65        &self.message
66    }
67
68    pub fn kind(&self) -> &ErrorKind {
69        &self.kind
70    }
71}
72
73impl error::Error for Error {
74    fn description(&self) -> &str {
75        &self.message
76    }
77
78    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
79        match self.kind() {
80            _ => None,
81        }
82    }
83}
84
85impl Into<String> for Error {
86    fn into(self) -> String {
87        self.message
88    }
89}
90
91impl fmt::Display for Error {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        write!(f, "{}", self.message)
94    }
95}
96
97#[cfg(feature = "async-native-tls")]
98impl From<async_native_tls::Error> for Error {
99    fn from(tls_error: async_native_tls::Error) -> Self {
100        Self::new(
101            ErrorKind::Tls(tls_error),
102            "Error creating secure connection",
103        )
104    }
105}
106
107impl From<IoError> for Error {
108    fn from(io_error: IoError) -> Self {
109        Self::new(ErrorKind::Io(io_error), "Error with connection to server")
110    }
111}
112
113impl From<ParseIntError> for Error {
114    fn from(parse_int_error: ParseIntError) -> Self {
115        Self::new(ErrorKind::ParseInt(parse_int_error), "Failed to parse int")
116    }
117}
118
119impl From<Utf8Error> for Error {
120    fn from(error: Utf8Error) -> Self {
121        Self::new(ErrorKind::ParseString(error), "Failed to parse string")
122    }
123}
124
125#[cfg(feature = "sasl")]
126impl From<base64::DecodeError> for Error {
127    fn from(error: base64::DecodeError) -> Self {
128        Self::new(ErrorKind::DecodeBase64(error), "Failed to decode base64")
129    }
130}
131
132pub(crate) use err;
133
134pub type Result<T> = result::Result<T, Error>;