use std::error::Error;
use std::fmt;
use std::path::PathBuf;
use crate::ConfigFormat;
#[derive(Debug)]
pub struct HumusConfigError {
pub path: PathBuf,
pub cause: ErrorCause,
}
#[derive(Debug)]
pub enum ErrorCause {
FileRead(std::io::Error),
#[cfg(feature = "json")]
Json(serde_json::Error),
#[cfg(feature = "json5")]
Json5(json5::Error),
#[cfg(feature = "toml")]
Toml(toml::de::Error),
FormatNotAllowed {
format: ConfigFormat,
prefer: ConfigFormat,
},
}
impl ErrorCause {
pub fn get_format(&self) -> Option<ConfigFormat> {
match self {
Self::FileRead(_) => None,
#[cfg(feature = "json")]
Self::Json(_) => Some(ConfigFormat::Json),
#[cfg(feature = "json5")]
Self::Json5(_) => Some(ConfigFormat::Json5),
#[cfg(feature = "toml")]
Self::Toml(_) => Some(ConfigFormat::Toml),
Self::FormatNotAllowed { format, .. } => Some(*format),
}
}
}
impl fmt::Display for HumusConfigError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let path = &self.path;
match &self.cause {
ErrorCause::FileRead(io_error) => {
write!(f, "Error while reading file {path:?}: {io_error}")
}
#[cfg(feature = "json")]
ErrorCause::Json(error) => write!(f, "Unable to parse file as json {path:?}:\n{error}"),
#[cfg(feature = "json5")]
ErrorCause::Json5(error) => {
write!(f, "Unable to parse file as json5 {path:?}:\n{error}")
}
#[cfg(feature = "toml")]
ErrorCause::Toml(error) => write!(f, "Unable to parse file as toml {path:?}:\n{error}"),
ErrorCause::FormatNotAllowed { format, prefer } => write!(
f,
"Unable to parse file {path:?}: Using {format} here is not allowed, please prefer {prefer}. "
),
}
}
}
impl Error for HumusConfigError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match &self.cause {
ErrorCause::FileRead(error) => Some(error),
#[cfg(feature = "json")]
ErrorCause::Json(error) => Some(error),
#[cfg(feature = "json5")]
ErrorCause::Json5(error) => Some(error),
#[cfg(feature = "toml")]
ErrorCause::Toml(error) => Some(error),
ErrorCause::FormatNotAllowed { .. } => None,
}
}
}