1use std::{env::VarError, io, num::ParseIntError, path::PathBuf, str::ParseBoolError};
2
3use derive_more::derive::{Display, Error};
4#[cfg(feature = "openssl")]
5use openssl::error::ErrorStack as OpenSSLError;
6#[cfg(feature = "rustls-0_23")]
7use rustls_0_23::Error as Rustls023Error;
8use toml::de::Error as TomlError;
9
10#[derive(Debug, Display, Error)]
12pub enum Error {
13 #[display("Env var error: {_0}")]
15 EnvVarError(VarError),
16
17 #[display("File exists: {}", _0.display())]
19 FileExists(#[error(not(source))] PathBuf),
20
21 #[allow(missing_docs)]
23 #[display("Expected {expected}, got {got} (@ {file}:{line}:{column})")]
24 InvalidValue {
25 expected: &'static str,
26 got: String,
27 file: &'static str,
28 line: u32,
29 column: u32,
30 },
31
32 #[display("I/O error: {_0}")]
34 IoError(io::Error),
35
36 #[cfg(feature = "openssl")]
38 #[display("OpenSSL error: {_0}")]
39 OpenSSLError(OpenSSLError),
40
41 #[cfg(feature = "rustls-0_23")]
43 #[display("Rustls error: {_0}")]
44 RustlsError(#[error(not(source))] String),
45
46 #[display("Failed to parse boolean: {_0}")]
48 ParseBoolError(ParseBoolError),
49
50 #[display("Failed to parse integer: {_0}")]
52 ParseIntError(ParseIntError),
53
54 #[display("Failed to parse address: {_0}")]
56 ParseAddressError(#[error(not(source))] String),
57
58 #[display("TOML error: {_0}")]
60 TomlError(TomlError),
61}
62
63macro_rules! InvalidValue {
64 (expected: $expected:expr, got: $got:expr,) => {
65 crate::Error::InvalidValue {
66 expected: $expected,
67 got: $got.to_string(),
68 file: file!(),
69 line: line!(),
70 column: column!(),
71 }
72 };
73}
74
75impl From<io::Error> for Error {
76 fn from(err: io::Error) -> Self {
77 Self::IoError(err)
78 }
79}
80
81#[cfg(feature = "openssl")]
82impl From<OpenSSLError> for Error {
83 fn from(err: OpenSSLError) -> Self {
84 Self::OpenSSLError(err)
85 }
86}
87
88#[cfg(feature = "rustls-0_23")]
89impl From<Rustls023Error> for Error {
90 fn from(err: Rustls023Error) -> Self {
91 Self::RustlsError(err.to_string())
92 }
93}
94
95impl From<ParseBoolError> for Error {
96 fn from(err: ParseBoolError) -> Self {
97 Self::ParseBoolError(err)
98 }
99}
100
101impl From<ParseIntError> for Error {
102 fn from(err: ParseIntError) -> Self {
103 Self::ParseIntError(err)
104 }
105}
106
107impl From<TomlError> for Error {
108 fn from(err: TomlError) -> Self {
109 Self::TomlError(err)
110 }
111}
112
113impl From<VarError> for Error {
114 fn from(err: VarError) -> Self {
115 Self::EnvVarError(err)
116 }
117}
118
119impl From<Error> for io::Error {
120 fn from(err: Error) -> Self {
121 match err {
122 Error::EnvVarError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
123
124 Error::FileExists(_) => io::Error::new(io::ErrorKind::AlreadyExists, err.to_string()),
125
126 Error::InvalidValue { .. } => {
127 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
128 }
129
130 Error::IoError(io_error) => io_error,
131
132 #[cfg(feature = "openssl")]
133 Error::OpenSSLError(ossl_error) => io::Error::other(ossl_error),
134
135 #[cfg(feature = "rustls-0_23")]
136 Error::RustlsError(_) => io::Error::new(io::ErrorKind::InvalidData, err.to_string()),
137
138 Error::ParseBoolError(_) => {
139 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
140 }
141
142 Error::ParseIntError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
143
144 Error::ParseAddressError(_) => {
145 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
146 }
147
148 Error::TomlError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
149 }
150 }
151}