diff options
Diffstat (limited to 'src/deserializer/mod.rs')
-rw-r--r-- | src/deserializer/mod.rs | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/deserializer/mod.rs b/src/deserializer/mod.rs index d6af9c1..918136f 100644 --- a/src/deserializer/mod.rs +++ b/src/deserializer/mod.rs @@ -196,7 +196,85 @@ impl From<Error<Error<Infallible>>> for Error<Infallible> } } +impl<DeError> Error<DeError> +{ + /// Converts `Self` into `Err`. + pub fn into_error<Err>(self) -> Err + where + Err: From<DeError> + From<Error<Infallible>>, + { + if let Error::DeserializeFailed(de_err) = self { + return de_err.into(); + } + + self.into_never_de_err().into() + } +} + /// XML error. #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct XMLError(#[from] quick_xml::Error); + +/// Implements conversion from [`Error`] with [`From`] for the given error type. +/// +/// Allows for custom error types with source error types to easily be converted into with +/// `?`. +/// +/// The given error type should implement `From<Error<Infallible>>`. +/// +/// # Examples +/// ``` +/// use std::convert::Infallible; +/// +/// use xml_stinks::deserializer::Error as DeserializerError; +/// use xml_stinks::impl_from_deserializer_error; +/// +/// #[derive(Debug, thiserror::Error)] +/// enum FooError +/// { +/// #[error("Deserialization failed")] +/// DeserializeFailed(#[from] DeserializerError<Infallible>), +/// +/// #[error("Invalid bar")] +/// InvalidBar(#[from] BarError), +/// } +/// +/// impl_from_deserializer_error!(FooError); +/// +/// #[derive(Debug, thiserror::Error)] +/// enum BarError +/// { +/// #[error("Oops")] +/// Oops, +/// } +/// +/// let err_a: FooError = DeserializerError::<Infallible>::UnexpectedEndOfFile.into(); +/// +/// assert!(matches!( +/// err_a, +/// FooError::DeserializeFailed(DeserializerError::UnexpectedEndOfFile) +/// )); +/// +/// let err_b: FooError = DeserializerError::DeserializeFailed(BarError::Oops).into(); +/// +/// assert!(matches!(err_b, FooError::InvalidBar(BarError::Oops))); +/// ``` +#[macro_export] +macro_rules! impl_from_deserializer_error { + ($err: path) => { + impl<DeError: Into<Self>> From<::xml_stinks::deserializer::Error<DeError>> + for $err + { + fn from(err: ::xml_stinks::deserializer::Error<DeError>) -> Self + { + if let ::xml_stinks::deserializer::Error::DeserializeFailed(de_err) = err + { + return de_err.into(); + } + + err.into_never_de_err().into() + } + } + }; +} |