mod file_resolver;
mod many_resolver;
mod noop_resolver;
#[cfg(feature = "web-resolver")]
mod web_resolver;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use url::Url;
use xsd_parser_types::misc::Namespace;
pub use self::file_resolver::FileResolver;
pub use self::many_resolver::ManyResolver;
pub use self::noop_resolver::NoOpResolver;
#[cfg(feature = "web-resolver")]
pub use self::web_resolver::WebResolver;
pub trait Resolver: Debug {
type Buffer;
type Error: Display;
#[allow(clippy::type_complexity)]
fn resolve(&mut self, req: &ResolveRequest) -> ResolveResult<Self>;
}
pub type ResolveResult<R> =
Result<Option<(Option<String>, Url, <R as Resolver>::Buffer)>, <R as Resolver>::Error>;
#[must_use]
#[derive(Debug)]
pub struct ResolveRequest {
pub requested_location: String,
pub requested_ns: Option<Namespace>,
pub current_location: Option<Url>,
pub current_ns: Option<Namespace>,
pub request_type: ResolveRequestType,
}
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
pub enum ResolveRequestType {
#[default]
UserDefined,
IncludeRequest,
ImportRequest,
}
impl ResolveRequest {
pub fn new<X: Into<String>>(requested_location: X, request_type: ResolveRequestType) -> Self {
Self {
requested_location: requested_location.into(),
requested_ns: None,
current_location: None,
current_ns: None,
request_type,
}
}
pub fn requested_ns(mut self, ns: Namespace) -> Self {
self.requested_ns = Some(ns);
self
}
pub fn current_ns(mut self, ns: Namespace) -> Self {
self.current_ns = Some(ns);
self
}
pub fn current_location<X: Into<Url>>(mut self, location: X) -> Self {
self.current_location = Some(location.into());
self
}
}
impl Display for ResolveRequest {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "Location={}", self.requested_location)?;
if let Some(ns) = &self.requested_ns {
write!(f, "({})", ns)?;
}
if let Some(current) = &self.current_location {
write!(f, "Current={}", current)?;
}
if let Some(current_ns) = &self.current_ns {
write!(f, "({})", current_ns)?;
}
Ok(())
}
}
fn strip_name_ext(s: &str) -> &str {
if let Some(s) = s.strip_suffix(".xml") {
s
} else if let Some(s) = s.strip_suffix(".xsd") {
s
} else {
s
}
}