use crate::escape::EscapeError;
use crate::events::attributes::AttrError;
use std::str::Utf8Error;
#[derive(Debug)]
pub enum Error {
Io(::std::io::Error),
Utf8(Utf8Error),
UnexpectedEof(String),
EndEventMismatch {
expected: String,
found: String,
},
UnexpectedToken(String),
UnexpectedBang(u8),
TextNotFound,
XmlDeclWithoutVersion(Option<String>),
InvalidAttr(AttrError),
EscapeError(EscapeError),
}
impl From<::std::io::Error> for Error {
#[inline]
fn from(error: ::std::io::Error) -> Error {
Error::Io(error)
}
}
impl From<Utf8Error> for Error {
#[inline]
fn from(error: Utf8Error) -> Error {
Error::Utf8(error)
}
}
impl From<EscapeError> for Error {
#[inline]
fn from(error: EscapeError) -> Error {
Error::EscapeError(error)
}
}
impl From<AttrError> for Error {
#[inline]
fn from(error: AttrError) -> Self {
Error::InvalidAttr(error)
}
}
pub type Result<T> = std::result::Result<T, Error>;
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Error::Io(e) => write!(f, "I/O error: {}", e),
Error::Utf8(e) => write!(f, "UTF8 error: {}", e),
Error::UnexpectedEof(e) => write!(f, "Unexpected EOF during reading {}", e),
Error::EndEventMismatch { expected, found } => {
write!(f, "Expecting </{}> found </{}>", expected, found)
}
Error::UnexpectedToken(e) => write!(f, "Unexpected token '{}'", e),
Error::UnexpectedBang(b) => write!(
f,
"Only Comment (`--`), CDATA (`[CDATA[`) and DOCTYPE (`DOCTYPE`) nodes can start with a '!', but symbol `{}` found",
*b as char
),
Error::TextNotFound => write!(f, "Cannot read text, expecting Event::Text"),
Error::XmlDeclWithoutVersion(e) => write!(
f,
"XmlDecl must start with 'version' attribute, found {:?}",
e
),
Error::InvalidAttr(e) => write!(f, "error while parsing attribute: {}", e),
Error::EscapeError(e) => write!(f, "{}", e),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Io(e) => Some(e),
Error::Utf8(e) => Some(e),
Error::InvalidAttr(e) => Some(e),
Error::EscapeError(e) => Some(e),
_ => None,
}
}
}
#[cfg(feature = "serialize")]
pub mod serialize {
use super::*;
use std::fmt;
use std::num::{ParseFloatError, ParseIntError};
#[derive(Debug)]
pub enum DeError {
Custom(String),
Int(ParseIntError),
Float(ParseFloatError),
Xml(Error),
EndOfAttributes,
Eof,
InvalidBoolean(String),
InvalidEnum(crate::events::Event<'static>),
Text,
Start,
End,
Unsupported(&'static str),
}
impl fmt::Display for DeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DeError::Custom(s) => write!(f, "{}", s),
DeError::Xml(e) => write!(f, "{}", e),
DeError::Int(e) => write!(f, "{}", e),
DeError::Float(e) => write!(f, "{}", e),
DeError::EndOfAttributes => write!(f, "Unexpected end of attributes"),
DeError::Eof => write!(f, "Unexpected `Event::Eof`"),
DeError::InvalidBoolean(v) => write!(f, "Invalid boolean value '{}'", v),
DeError::InvalidEnum(e) => write!(
f,
"Invalid event for Enum, expecting Text or Start, got: {:?}",
e
),
DeError::Text => write!(f, "Expecting Text event"),
DeError::Start => write!(f, "Expecting Start event"),
DeError::End => write!(f, "Expecting End event"),
DeError::Unsupported(s) => write!(f, "Unsupported operation {}", s),
}
}
}
impl ::std::error::Error for DeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
DeError::Int(e) => Some(e),
DeError::Float(e) => Some(e),
DeError::Xml(e) => Some(e),
_ => None,
}
}
}
impl serde::de::Error for DeError {
fn custom<T: fmt::Display>(msg: T) -> Self {
DeError::Custom(msg.to_string())
}
}
impl serde::ser::Error for DeError {
fn custom<T: fmt::Display>(msg: T) -> Self {
DeError::Custom(msg.to_string())
}
}
impl From<Error> for DeError {
fn from(e: Error) -> Self {
DeError::Xml(e)
}
}
impl From<EscapeError> for DeError {
#[inline]
fn from(e: EscapeError) -> Self {
Self::Xml(e.into())
}
}
impl From<ParseIntError> for DeError {
fn from(e: ParseIntError) -> Self {
DeError::Int(e)
}
}
impl From<ParseFloatError> for DeError {
fn from(e: ParseFloatError) -> Self {
DeError::Float(e)
}
}
impl From<AttrError> for DeError {
#[inline]
fn from(e: AttrError) -> Self {
DeError::Xml(e.into())
}
}
}