scratchstack_config/
error.rs

1use {
2    rustls::Error as TlsError,
3    std::{
4        error::Error,
5        fmt::{Debug, Display, Formatter, Result as FmtResult},
6        io::Error as IOError,
7        net::AddrParseError,
8        str::Utf8Error,
9    },
10    toml::de::Error as TomlDeError,
11};
12
13#[derive(Debug)]
14pub enum ConfigError {
15    DeserError(TomlDeError),
16    IO(IOError),
17    InvalidConfig(String),
18    InvalidTlsConfig(TlsConfigErrorKind),
19    InvalidDatabaseConfig(DatabaseConfigErrorKind),
20    InvalidAddress(AddrParseError),
21    InvalidPartition,
22    InvalidPort,
23    InvalidRegion,
24}
25
26impl Display for ConfigError {
27    fn fmt(&self, f: &mut Formatter) -> FmtResult {
28        match &self {
29            Self::DeserError(e) => write!(f, "Deserialization error: {e}"),
30            Self::IO(e) => write!(f, "I/O error: {e}"),
31            Self::InvalidConfig(msg) => write!(f, "Invalid config: {msg}"),
32            Self::InvalidTlsConfig(e) => write!(f, "Invalid TLS configuration: {e}"),
33            Self::InvalidDatabaseConfig(e) => write!(f, "Invalid database configuration: {e}"),
34            Self::InvalidAddress(e) => write!(f, "Invalid address: {e}"),
35            Self::InvalidPartition => write!(f, "Invalid partition"),
36            Self::InvalidPort => write!(f, "Invalid port"),
37            Self::InvalidRegion => write!(f, "Invalid region"),
38        }
39    }
40}
41
42impl Error for ConfigError {
43    fn source(&self) -> Option<&(dyn Error + 'static)> {
44        match self {
45            Self::IO(e) => Some(e),
46            Self::DeserError(e) => Some(e),
47            Self::InvalidTlsConfig(TlsConfigErrorKind::TlsSetupFailed(e)) => Some(e),
48            Self::InvalidDatabaseConfig(DatabaseConfigErrorKind::InvalidPasswordFileEncoding(_, e)) => Some(e),
49            Self::InvalidAddress(e) => Some(e),
50            _ => None,
51        }
52    }
53}
54
55impl From<AddrParseError> for ConfigError {
56    fn from(e: AddrParseError) -> Self {
57        ConfigError::InvalidAddress(e)
58    }
59}
60
61impl From<DatabaseConfigErrorKind> for ConfigError {
62    fn from(e: DatabaseConfigErrorKind) -> Self {
63        ConfigError::InvalidDatabaseConfig(e)
64    }
65}
66
67impl From<IOError> for ConfigError {
68    fn from(e: IOError) -> Self {
69        ConfigError::IO(e)
70    }
71}
72
73impl From<TlsConfigErrorKind> for ConfigError {
74    fn from(e: TlsConfigErrorKind) -> Self {
75        ConfigError::InvalidTlsConfig(e)
76    }
77}
78
79impl From<TomlDeError> for ConfigError {
80    fn from(e: TomlDeError) -> Self {
81        ConfigError::DeserError(e)
82    }
83}
84
85#[derive(Debug)]
86pub enum DatabaseConfigErrorKind {
87    InvalidPasswordFileEncoding(String, Utf8Error),
88    MissingPassword,
89}
90
91impl Display for DatabaseConfigErrorKind {
92    fn fmt(&self, f: &mut Formatter) -> FmtResult {
93        match &self {
94            Self::InvalidPasswordFileEncoding(s, e) => write!(f, "Invalid password file encoding: {s}: {e}"),
95            Self::MissingPassword => {
96                write!(f, "Database URL specifies a password placeholder but a password was not supplied")
97            }
98        }
99    }
100}
101
102#[derive(Debug)]
103pub enum TlsConfigErrorKind {
104    TlsSetupFailed(TlsError),
105    InvalidCertificate,
106    InvalidPrivateKey,
107}
108
109impl Display for TlsConfigErrorKind {
110    fn fmt(&self, f: &mut Formatter) -> FmtResult {
111        match &self {
112            TlsConfigErrorKind::TlsSetupFailed(e) => {
113                write!(f, "Invalid TLS configuration: {e}")
114            }
115            TlsConfigErrorKind::InvalidCertificate => {
116                write!(f, "Invalid certificate")
117            }
118            TlsConfigErrorKind::InvalidPrivateKey => {
119                write!(f, "Invalid private key")
120            }
121        }
122    }
123}