use std::fmt::{Display, Formatter, Result as FmtResult};
use std::io::Error as IoError;
use std::path::PathBuf;
use thiserror::Error;
use url::{ParseError as UrlParseError, Url};
use xsd_parser_types::misc::Namespace;
use xsd_parser_types::quick_xml::Error as XmlError;
use super::resolver::ResolveRequest;
#[derive(Debug, Error)]
pub enum Error<E> {
#[error("IO Error: {0}")]
IoError(#[from] IoError),
#[error("{0}")]
XmlError(#[from] XmlErrorWithLocation),
#[error("URL Parse Error: {0}")]
UrlParseError(#[from] UrlParseError),
#[error("Unable to resolve requested resource: {0}")]
UnableToResolve(Box<ResolveRequest>),
#[error(
"Mismatching target namespace (location={location}, found={found}, expected={expected})"
)]
MismatchingTargetNamespace {
location: Url,
found: Namespace,
expected: Namespace,
},
#[error("Resolver Error: {0}")]
Resolver(E),
#[error("Invalid file path: {0}!")]
InvalidFilePath(PathBuf),
}
impl<E> Error<E> {
pub fn resolver<X: Into<E>>(error: X) -> Self {
Self::Resolver(error.into())
}
}
#[derive(Debug, Error)]
pub struct XmlErrorWithLocation {
pub error: XmlError,
pub location: Option<Url>,
}
impl From<XmlError> for XmlErrorWithLocation {
fn from(error: XmlError) -> Self {
Self {
error,
location: None,
}
}
}
impl Display for XmlErrorWithLocation {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
let Self { error, location } = self;
write!(f, "XML Error: ")?;
error.fmt(f)?;
if let Some(location) = location {
write!(f, "\n in schema ")?;
location.fmt(f)?;
}
Ok(())
}
}