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