1use std::error;
14use std::fmt;
15use std::io;
16use std::sync::Arc;
17
18use futures_channel::mpsc;
19
20use crate::resp;
21
22#[derive(Debug, Clone)]
23pub enum Error {
24 Internal(String),
26
27 IO(Arc<io::Error>),
29
30 Resp(String, Option<resp::RespValue>),
32
33 Remote(String),
35
36 Connection(ConnectionReason),
38
39 Unexpected(String),
47
48 #[cfg(feature = "with-rustls")]
49 InvalidDnsName,
50
51 #[cfg(feature = "with-native-tls")]
52 Tls(Arc<native_tls::Error>),
53}
54
55pub(crate) fn internal(msg: impl Into<String>) -> Error {
56 Error::Internal(msg.into())
57}
58
59pub(crate) fn unexpected(msg: impl Into<String>) -> Error {
60 Error::Unexpected(msg.into())
61}
62
63pub(crate) fn resp(msg: impl Into<String>, resp: resp::RespValue) -> Error {
64 Error::Resp(msg.into(), Some(resp))
65}
66
67impl From<io::Error> for Error {
68 fn from(err: io::Error) -> Error {
69 Error::IO(Arc::new(err))
70 }
71}
72
73impl<T: 'static + Send> From<mpsc::TrySendError<T>> for Error {
74 fn from(err: mpsc::TrySendError<T>) -> Error {
75 Error::Unexpected(format!("Cannot write to channel: {}", err))
76 }
77}
78
79impl error::Error for Error {
80 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
81 match self {
82 Error::IO(err) => Some(err),
83 #[cfg(feature = "with-native-tls")]
84 Error::Tls(err) => Some(err),
85 _ => None,
86 }
87 }
88}
89
90#[cfg(feature = "with-native-tls")]
91impl From<native_tls::Error> for Error {
92 fn from(err: native_tls::Error) -> Error {
93 Error::Tls(Arc::new(err))
94 }
95}
96
97impl fmt::Display for Error {
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99 match self {
100 Error::Internal(s) => write!(f, "{}", s),
101 Error::IO(err) => write!(f, "{}", err),
102 Error::Resp(s, resp) => write!(f, "{}: {:?}", s, resp),
103 Error::Remote(s) => write!(f, "{}", s),
104 Error::Connection(ConnectionReason::Connected) => {
105 write!(f, "Connection already established")
106 }
107 Error::Connection(ConnectionReason::Connecting) => write!(f, "Connection in progress"),
108 Error::Connection(ConnectionReason::ConnectionFailed) => {
109 write!(f, "The last attempt to establish a connection failed")
110 }
111 Error::Connection(ConnectionReason::NotConnected) => {
112 write!(f, "Connection has been closed")
113 }
114 #[cfg(feature = "with-rustls")]
115 Error::InvalidDnsName => {
116 write!(f, "Invalid dns name")
117 }
118 #[cfg(feature = "with-native-tls")]
119 Error::Tls(err) => write!(f, "{}", err),
120 Error::Unexpected(err) => write!(f, "{}", err),
121 }
122 }
123}
124
125#[derive(Debug, Copy, Clone)]
127pub enum ConnectionReason {
128 Connecting,
131 Connected,
134 ConnectionFailed,
137 NotConnected,
140}