use crate::Location;
use std::fmt::{self, Display, Formatter};
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
InvalidUtf8 {
location: Box<Location>,
},
UnsupportedType {
location: Box<Location>,
found: &'static str,
},
Parse {
location: Option<Box<Location>>,
message: String,
},
#[cfg(feature = "serde")]
Deserialize {
message: String,
location: Option<Box<Location>>,
},
}
impl Error {
#[cfg(feature = "serde")]
pub(crate) fn or_location(mut self, location: &Location) -> Self {
if let Self::Deserialize {
location: slot @ None,
..
} = &mut self
{
*slot = Some(Box::new(location.clone()));
}
self
}
}
fn located_message(location: &Location, message: &str) -> String {
format!("{message} at {location}")
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidUtf8 { location } => {
write!(f, "invalid utf-8 in configuration input from {location}")?;
}
Self::UnsupportedType { location, found } => {
write!(
f,
"{}",
located_message(
location,
&format!("unsupported configuration input type `{found}`"),
)
)?;
}
Self::Parse {
location: Some(location),
message,
} => write!(f, "{}", located_message(location, message))?,
Self::Parse { message, .. } => write!(f, "{message}")?,
#[cfg(feature = "serde")]
Self::Deserialize {
message,
location: Some(location),
} => write!(
f,
"{}",
located_message(
location,
&format!("failed to deserialize configuration: {message}"),
)
)?,
#[cfg(feature = "serde")]
Self::Deserialize { message, .. } => {
write!(f, "failed to deserialize configuration: {message}")?
}
}
if f.alternate() {
let location = match self {
Self::InvalidUtf8 { location } | Self::UnsupportedType { location, .. } => {
Some(location.as_ref())
}
Self::Parse {
location: Some(location),
..
} => Some(location.as_ref()),
#[cfg(feature = "serde")]
Self::Deserialize {
location: Some(location),
..
} => Some(location.as_ref()),
_ => None,
};
if let Some(location) = location
&& !location.snippet.is_empty()
{
write!(f, "\n{}", location.snippet)?;
}
}
Ok(())
}
}
impl std::error::Error for Error {}