xsd_parser/models/schema/
mod.rs1pub mod xs;
10
11mod occurs;
12
13use std::collections::btree_map::{BTreeMap, Iter, IterMut};
14use std::ops::Deref;
15
16use url::Url;
17
18use xsd_parser_types::misc::{Namespace, NamespacePrefix};
19
20use self::xs::Schema;
21
22pub use xsd_parser_types::xml::QName;
23
24pub use self::occurs::{MaxOccurs, MinOccurs};
25
26#[derive(Debug)]
39pub struct Schemas {
40 pub(crate) schemas: SchemaFiles,
41 pub(crate) namespace_infos: NamespaceInfos,
42
43 pub(crate) known_prefixes: NamespacePrefixes,
44 pub(crate) known_namespaces: Namespaces,
45
46 pub(crate) last_schema_id: usize,
47 pub(crate) last_namespace_id: usize,
48}
49
50#[derive(Debug)]
52pub struct NamespaceInfo {
53 pub prefix: Option<NamespacePrefix>,
55
56 pub namespace: Option<Namespace>,
58
59 pub schemas: Vec<SchemaId>,
61
62 pub module_name: Option<String>,
64}
65
66#[derive(Debug)]
68pub struct SchemaInfo {
69 pub name: Option<String>,
71
72 pub schema: Schema,
74
75 pub location: Option<Url>,
77
78 pub(crate) namespace_id: NamespaceId,
80
81 pub(crate) dependencies: BTreeMap<String, Dependency<SchemaId>>,
83}
84
85#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
87pub enum Dependency<T> {
88 Include(T),
90
91 Import(T),
93
94 Override(T),
96
97 Redefine(T),
99}
100
101#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
103pub struct SchemaId(pub usize);
104
105#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
107pub struct NamespaceId(pub usize);
108
109pub type SchemaFiles = BTreeMap<SchemaId, SchemaInfo>;
111
112pub type NamespaceInfos = BTreeMap<NamespaceId, NamespaceInfo>;
114
115pub type Namespaces = BTreeMap<Option<Namespace>, NamespaceId>;
117
118pub type NamespacePrefixes = BTreeMap<NamespacePrefix, NamespaceId>;
120
121impl Schemas {
124 pub fn schemas(&self) -> Iter<'_, SchemaId, SchemaInfo> {
126 self.schemas.iter()
127 }
128
129 pub fn schemas_mut(&mut self) -> IterMut<'_, SchemaId, SchemaInfo> {
131 self.schemas.iter_mut()
132 }
133
134 pub fn namespaces(&self) -> Iter<'_, NamespaceId, NamespaceInfo> {
137 self.namespace_infos.iter()
138 }
139
140 #[must_use]
143 pub fn get_schema(&self, id: &SchemaId) -> Option<&SchemaInfo> {
144 self.schemas.get(id)
145 }
146
147 #[must_use]
150 pub fn get_schema_mut(&mut self, id: &SchemaId) -> Option<&mut SchemaInfo> {
151 self.schemas.get_mut(id)
152 }
153
154 #[must_use]
157 pub fn get_namespace_info(&self, id: &NamespaceId) -> Option<&NamespaceInfo> {
158 self.namespace_infos.get(id)
159 }
160
161 #[must_use]
164 pub fn get_namespace_info_mut(&mut self, id: &NamespaceId) -> Option<&mut NamespaceInfo> {
165 self.namespace_infos.get_mut(id)
166 }
167
168 #[must_use]
171 pub fn get_namespace_info_by_namespace(
172 &self,
173 ns: &Option<Namespace>,
174 ) -> Option<&NamespaceInfo> {
175 let id = self.resolve_namespace(ns)?;
176
177 self.get_namespace_info(&id)
178 }
179
180 #[must_use]
184 pub fn resolve_prefix(&self, prefix: &NamespacePrefix) -> Option<NamespaceId> {
185 Some(*self.known_prefixes.get(prefix)?)
186 }
187
188 #[must_use]
192 pub fn resolve_namespace(&self, ns: &Option<Namespace>) -> Option<NamespaceId> {
193 Some(*self.known_namespaces.get(ns)?)
194 }
195
196 #[must_use]
197 pub(crate) fn next_schema_id(&mut self) -> SchemaId {
198 self.last_schema_id = self.last_schema_id.wrapping_add(1);
199
200 SchemaId(self.last_schema_id)
201 }
202}
203
204impl Default for Schemas {
205 fn default() -> Self {
206 Self {
207 schemas: SchemaFiles::default(),
208 namespace_infos: NamespaceInfos::default(),
209
210 known_prefixes: NamespacePrefixes::default(),
211 known_namespaces: Namespaces::default(),
212
213 last_schema_id: SchemaId::UNKNOWN.0,
214 last_namespace_id: NamespaceId::ANONYMOUS.0,
215 }
216 }
217}
218
219impl NamespaceInfo {
222 #[must_use]
224 pub fn new(namespace: Option<Namespace>) -> Self {
225 Self {
226 prefix: None,
227 namespace,
228 schemas: Vec::new(),
229 module_name: None,
230 }
231 }
232
233 #[must_use]
238 pub fn name(&self) -> Option<String> {
239 self.module_name
240 .clone()
241 .or_else(|| self.prefix.as_ref().map(ToString::to_string))
242 }
243}
244
245impl SchemaInfo {
248 #[must_use]
250 pub fn namespace_id(&self) -> NamespaceId {
251 self.namespace_id
252 }
253
254 #[must_use]
256 pub fn dependencies(&self) -> &BTreeMap<String, Dependency<SchemaId>> {
257 &self.dependencies
258 }
259
260 #[must_use]
262 pub fn depends_on(&self, schema_id: &SchemaId) -> bool {
263 self.dependencies
264 .values()
265 .any(|id| id.as_ref() == schema_id)
266 }
267}
268
269impl<T> Dependency<T> {
272 pub fn map<F, U>(self, f: F) -> Dependency<U>
274 where
275 F: FnOnce(T) -> U,
276 {
277 match self {
278 Dependency::Include(x) => Dependency::Include(f(x)),
279 Dependency::Import(x) => Dependency::Import(f(x)),
280 Dependency::Override(x) => Dependency::Override(f(x)),
281 Dependency::Redefine(x) => Dependency::Redefine(f(x)),
282 }
283 }
284}
285
286impl<T> Deref for Dependency<T> {
287 type Target = T;
288
289 fn deref(&self) -> &Self::Target {
290 match self {
291 Dependency::Include(x)
292 | Dependency::Import(x)
293 | Dependency::Override(x)
294 | Dependency::Redefine(x) => x,
295 }
296 }
297}
298
299impl<T> AsRef<T> for Dependency<T> {
300 fn as_ref(&self) -> &T {
301 match self {
302 Dependency::Include(x)
303 | Dependency::Import(x)
304 | Dependency::Override(x)
305 | Dependency::Redefine(x) => x,
306 }
307 }
308}
309
310impl SchemaId {
313 pub const UNKNOWN: Self = Self(0);
315
316 #[must_use]
318 pub fn is_unknown(&self) -> bool {
319 self.eq(&Self::UNKNOWN)
320 }
321
322 #[inline]
324 #[must_use]
325 pub fn or(self, other: Self) -> Self {
326 if self.is_unknown() {
327 other
328 } else {
329 self
330 }
331 }
332}
333
334impl NamespaceId {
337 pub const UNKNOWN: Self = Self(0);
339
340 pub const ANONYMOUS: Self = Self(1);
342
343 #[inline]
345 #[must_use]
346 pub fn is_unknown(&self) -> bool {
347 self.eq(&Self::UNKNOWN)
348 }
349
350 #[inline]
352 #[must_use]
353 pub fn is_anonymous(&self) -> bool {
354 self.eq(&Self::ANONYMOUS)
355 }
356
357 #[inline]
359 #[must_use]
360 pub fn or(self, other: Self) -> Self {
361 if self.is_unknown() {
362 other
363 } else {
364 self
365 }
366 }
367}