aboutsummaryrefslogtreecommitdiff
path: root/src/deserializer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/deserializer/mod.rs')
-rw-r--r--src/deserializer/mod.rs78
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()
+ }
+ }
+ };
+}