error.rs

  1/*!
  2# Error types for XML parsing
  3
  4This module contains the error types used throughout the `xso` crate.
  5*/
  6// Copyright (c) 2024 Jonas Schäfer <jonas@zombofant.net>
  7//
  8// This Source Code Form is subject to the terms of the Mozilla Public
  9// License, v. 2.0. If a copy of the MPL was not distributed with this
 10// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 11use std::fmt;
 12
 13use rxml::error::XmlError;
 14
 15/// Error variants generated while parsing or serialising XML data.
 16#[derive(Debug)]
 17pub enum Error {
 18    /// Invalid XML data encountered
 19    XmlError(XmlError),
 20
 21    /// Attempt to parse text data failed with the provided nested error.
 22    TextParseError(Box<dyn std::error::Error + Send + Sync + 'static>),
 23
 24    /// An element header did not match an expected element.
 25    ///
 26    /// This is only rarely generated: most of the time, a mismatch of element
 27    /// types is reported as either an unexpected or a missing child element,
 28    /// errors which are generally more specific.
 29    TypeMismatch,
 30}
 31
 32impl fmt::Display for Error {
 33    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 34        match self {
 35            Self::XmlError(ref e) => write!(f, "xml parse error: {}", e),
 36            Self::TextParseError(ref e) => write!(f, "text parse error: {}", e),
 37            Self::TypeMismatch => f.write_str("mismatch between expected and actual XML data"),
 38        }
 39    }
 40}
 41
 42impl std::error::Error for Error {
 43    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
 44        match self {
 45            Self::XmlError(ref e) => Some(e),
 46            Self::TextParseError(ref e) => Some(&**e),
 47            _ => None,
 48        }
 49    }
 50}
 51
 52impl From<rxml::error::XmlError> for Error {
 53    fn from(other: rxml::error::XmlError) -> Error {
 54        Error::XmlError(other)
 55    }
 56}
 57
 58impl From<rxml::strings::Error> for Error {
 59    fn from(other: rxml::strings::Error) -> Error {
 60        Error::XmlError(other.into())
 61    }
 62}
 63
 64/// Error returned from
 65/// [`FromXml::from_events`][`crate::FromXml::from_events`].
 66#[derive(Debug)]
 67pub enum FromEventsError {
 68    /// The `name` and/or `attrs` passed to `FromXml::from_events` did not
 69    /// match the element's type.
 70    Mismatch {
 71        /// The `name` passed to `from_events`.
 72        name: rxml::QName,
 73
 74        /// The `attrs` passed to `from_events`.
 75        attrs: rxml::AttrMap,
 76    },
 77
 78    /// The `name` and `attrs` passed to `FromXml::from_events` matched the
 79    /// element's type, but the data was invalid. Details are in the inner
 80    /// error.
 81    Invalid(Error),
 82}
 83
 84impl From<Error> for FromEventsError {
 85    fn from(other: Error) -> Self {
 86        Self::Invalid(other)
 87    }
 88}
 89
 90impl fmt::Display for FromEventsError {
 91    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 92        match self {
 93            Self::Mismatch { .. } => f.write_str("element header did not match"),
 94            Self::Invalid(ref e) => fmt::Display::fmt(e, f),
 95        }
 96    }
 97}
 98
 99impl std::error::Error for FromEventsError {
100    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
101        match self {
102            Self::Mismatch { .. } => None,
103            Self::Invalid(ref e) => Some(e),
104        }
105    }
106}