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() +            } +        } +    }; +}  | 
