confpiler/
error.rs

1//! Crate error definitions and associated conversions
2use config::ConfigError;
3
4use crate::MergeWarning;
5
6/// Convenience alias for Results returned by this crate
7pub type Result<T> = std::result::Result<T, ConfpilerError>;
8
9/// ConfpilerError enumerates all possible errors returned by this library
10#[derive(Debug)]
11pub enum ConfpilerError {
12    /// All other instances of [ConfigError].
13    ConfigError(ConfigError),
14
15    /// Indicates a config file was specified more than once.
16    DuplicateConfig(String),
17
18    /// Indicates a config file would result in duplicated flattened keys.
19    DuplicateKey(String),
20
21    /// Indicates no config files specified when building a
22    /// [FlatConfig](crate::FlatConfig).
23    NoConfigSpecified,
24
25    /// Indicates a config contains an array that is unsupported.
26    ///
27    /// An unsupported array contains nested values.
28    UnsupportedArray(String),
29
30    /// This is a convenience wrapper for treating warnings as errors.
31    Warnings(Vec<MergeWarning>),
32}
33
34impl std::error::Error for ConfpilerError {
35    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
36        match *self {
37            ConfpilerError::ConfigError(_) => None,
38            ConfpilerError::DuplicateConfig(_) => None,
39            ConfpilerError::DuplicateKey(_) => None,
40            ConfpilerError::NoConfigSpecified => None,
41            ConfpilerError::UnsupportedArray(_) => None,
42            ConfpilerError::Warnings(_) => None,
43        }
44    }
45}
46
47impl std::fmt::Display for ConfpilerError {
48    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49        match *self {
50            ConfpilerError::ConfigError(ref err) => err.fmt(f),
51            ConfpilerError::DuplicateConfig(ref config) => {
52                write!(f, "the config \"{config}\" was specified twice")
53            }
54            ConfpilerError::DuplicateKey(ref key) => {
55                write!(f, "the key \"{key}\" would be overwritten by another value in the same configuration file")
56            }
57            ConfpilerError::NoConfigSpecified => {
58                write!(
59                    f,
60                    "must specify at least one config path via `builder.add_config`"
61                )
62            }
63            ConfpilerError::UnsupportedArray(ref key) => {
64                write!(f, "the array at \"{key}\" is unsupported (arrays must not contain arrays or maps to be condidered valid)")
65            }
66            ConfpilerError::Warnings(ref warnings) => {
67                let mut out = warnings
68                    .iter()
69                    .map(|w| w.to_string())
70                    .collect::<Vec<String>>();
71                out.sort();
72                write!(f, "{}", out.join("\n"))
73            }
74        }
75    }
76}
77
78impl From<ConfigError> for ConfpilerError {
79    fn from(err: ConfigError) -> ConfpilerError {
80        ConfpilerError::ConfigError(err)
81    }
82}
83
84impl From<Vec<MergeWarning>> for ConfpilerError {
85    fn from(value: Vec<MergeWarning>) -> ConfpilerError {
86        ConfpilerError::Warnings(value)
87    }
88}