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;
6use toml::de::Error as TomlError;
7
8#[derive(Debug, Display, Error)]
10pub enum Error {
11 #[display("Env var error: {_0}")]
13 EnvVarError(VarError),
14
15 #[display("File exists: {}", _0.display())]
17 FileExists(#[error(not(source))] PathBuf),
18
19 #[allow(missing_docs)]
21 #[display("Expected {expected}, got {got} (@ {file}:{line}:{column})")]
22 InvalidValue {
23 expected: &'static str,
24 got: String,
25 file: &'static str,
26 line: u32,
27 column: u32,
28 },
29
30 #[display("I/O error: {_0}")]
32 IoError(io::Error),
33
34 #[cfg(feature = "openssl")]
36 #[display("OpenSSL error: {_0}")]
37 OpenSSLError(OpenSSLError),
38
39 #[display("Failed to parse boolean: {_0}")]
41 ParseBoolError(ParseBoolError),
42
43 #[display("Failed to parse integer: {_0}")]
45 ParseIntError(ParseIntError),
46
47 #[display("Failed to parse address: {_0}")]
49 ParseAddressError(#[error(not(source))] String),
50
51 #[display("TOML error: {_0}")]
53 TomlError(TomlError),
54}
55
56macro_rules! InvalidValue {
57 (expected: $expected:expr, got: $got:expr,) => {
58 crate::Error::InvalidValue {
59 expected: $expected,
60 got: $got.to_string(),
61 file: file!(),
62 line: line!(),
63 column: column!(),
64 }
65 };
66}
67
68impl From<io::Error> for Error {
69 fn from(err: io::Error) -> Self {
70 Self::IoError(err)
71 }
72}
73
74#[cfg(feature = "openssl")]
75impl From<OpenSSLError> for Error {
76 fn from(err: OpenSSLError) -> Self {
77 Self::OpenSSLError(err)
78 }
79}
80
81impl From<ParseBoolError> for Error {
82 fn from(err: ParseBoolError) -> Self {
83 Self::ParseBoolError(err)
84 }
85}
86
87impl From<ParseIntError> for Error {
88 fn from(err: ParseIntError) -> Self {
89 Self::ParseIntError(err)
90 }
91}
92
93impl From<TomlError> for Error {
94 fn from(err: TomlError) -> Self {
95 Self::TomlError(err)
96 }
97}
98
99impl From<VarError> for Error {
100 fn from(err: VarError) -> Self {
101 Self::EnvVarError(err)
102 }
103}
104
105impl From<Error> for io::Error {
106 fn from(err: Error) -> Self {
107 match err {
108 Error::EnvVarError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
109
110 Error::FileExists(_) => io::Error::new(io::ErrorKind::AlreadyExists, err.to_string()),
111
112 Error::InvalidValue { .. } => {
113 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
114 }
115
116 Error::IoError(io_error) => io_error,
117
118 #[cfg(feature = "openssl")]
119 Error::OpenSSLError(ossl_error) => io::Error::other(ossl_error),
120
121 Error::ParseBoolError(_) => {
122 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
123 }
124
125 Error::ParseIntError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
126
127 Error::ParseAddressError(_) => {
128 io::Error::new(io::ErrorKind::InvalidInput, err.to_string())
129 }
130
131 Error::TomlError(_) => io::Error::new(io::ErrorKind::InvalidInput, err.to_string()),
132 }
133 }
134}