xsd_parser/pipeline/parser/resolver/
mod.rs1mod file_resolver;
4mod many_resolver;
5mod noop_resolver;
6
7#[cfg(feature = "web-resolver")]
8mod web_resolver;
9
10use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
11
12use url::Url;
13
14use crate::models::schema::Namespace;
15
16pub use self::file_resolver::FileResolver;
17pub use self::many_resolver::ManyResolver;
18pub use self::noop_resolver::NoOpResolver;
19
20#[cfg(feature = "web-resolver")]
21pub use self::web_resolver::WebResolver;
22
23pub trait Resolver: Debug {
26 type Buffer;
28
29 type Error: Display;
31
32 #[allow(clippy::type_complexity)]
45 fn resolve(&mut self, req: &ResolveRequest) -> ResolveResult<Self>;
46}
47
48pub type ResolveResult<R> =
50 Result<Option<(Option<String>, Url, <R as Resolver>::Buffer)>, <R as Resolver>::Error>;
51
52#[must_use]
54#[derive(Debug)]
55pub struct ResolveRequest {
56 pub requested_location: String,
58
59 pub requested_ns: Option<Namespace>,
61
62 pub current_location: Option<Url>,
64
65 pub current_ns: Option<Namespace>,
67
68 pub request_type: ResolveRequestType,
71}
72
73#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
75pub enum ResolveRequestType {
76 #[default]
78 UserDefined,
79 IncludeRequest,
81 ImportRequest,
83}
84
85impl ResolveRequest {
86 pub fn new<X: Into<String>>(requested_location: X, request_type: ResolveRequestType) -> Self {
88 Self {
89 requested_location: requested_location.into(),
90 requested_ns: None,
91
92 current_location: None,
93 current_ns: None,
94 request_type,
95 }
96 }
97
98 pub fn requested_ns(mut self, ns: Namespace) -> Self {
100 self.requested_ns = Some(ns);
101
102 self
103 }
104
105 pub fn current_ns(mut self, ns: Namespace) -> Self {
107 self.current_ns = Some(ns);
108
109 self
110 }
111
112 pub fn current_location<X: Into<Url>>(mut self, location: X) -> Self {
114 self.current_location = Some(location.into());
115
116 self
117 }
118}
119
120impl Display for ResolveRequest {
121 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
122 write!(f, "Location={}", self.requested_location)?;
123
124 if let Some(ns) = &self.requested_ns {
125 write!(f, "({})", ns)?;
126 }
127
128 if let Some(current) = &self.current_location {
129 write!(f, "Current={}", current)?;
130 }
131
132 if let Some(current_ns) = &self.current_ns {
133 write!(f, "({})", current_ns)?;
134 }
135
136 Ok(())
137 }
138}
139
140fn strip_name_ext(s: &str) -> &str {
141 if let Some(s) = s.strip_suffix(".xml") {
142 s
143 } else if let Some(s) = s.strip_suffix(".xsd") {
144 s
145 } else {
146 s
147 }
148}