use winnow::error::ContextError;
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Error {
Parse(ParseError),
#[cfg(feature = "serde")]
Deserialize(DeserializeError),
Convert {
from: &'static str,
to: &'static str,
},
Datetime,
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Parse(p) => Some(p),
#[cfg(feature = "serde")]
Error::Deserialize(d) => Some(d),
Error::Convert { .. } => None,
Error::Datetime => None,
}
}
}
impl alloc::fmt::Display for Error {
fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
match self {
Error::Parse(p) => write!(f, "{p}"),
#[cfg(feature = "serde")]
Error::Deserialize(s) => write!(f, "{s}"),
Error::Convert { from, to } => write!(f, "cannot convert from {from} to {to}"),
Error::Datetime => write!(f, "invalid date and time encoding"),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParseError {
pub(crate) context: ContextError,
}
impl ParseError {
pub(crate) fn new(context: ContextError) -> Self {
Self { context }
}
}
impl alloc::fmt::Display for ParseError {
fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
write!(f, "{}", self.context)
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
#[cfg(feature = "serde")]
#[derive(Debug, Clone, PartialEq)]
pub struct DeserializeError {
pub(crate) de: serde::de::value::Error,
}
#[cfg(feature = "serde")]
impl serde::de::Error for Error {
fn custom<T: alloc::fmt::Display>(msg: T) -> Self {
Self::Deserialize(DeserializeError {
de: serde::de::value::Error::custom(msg),
})
}
}
#[cfg(feature = "serde")]
impl From<serde::de::value::Error> for Error {
fn from(e: serde::de::value::Error) -> Self {
Self::Deserialize(DeserializeError { de: e })
}
}
#[cfg(feature = "serde")]
impl alloc::fmt::Display for DeserializeError {
fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result {
write!(f, "{}", self.de)
}
}
#[cfg(all(feature = "std", feature = "serde"))]
impl std::error::Error for DeserializeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.de)
}
}