xsd_parser/parser/resolver/
mod.rs

1//! Defines the [`Resolver`] trait and different resolver implementations.
2
3mod 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::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
23/// Trait that defines a so called resolver that can be used to load schema
24/// information from different sources.
25pub trait Resolver: Debug {
26    /// Buffer that contains the data of the resolved schema.
27    type Buffer;
28
29    /// Error that is returned by the resolver.
30    type Error: Display;
31
32    /// Try to resolve the schema information from the passed request.
33    ///
34    /// This methods tries to resolve the schema information by using the
35    /// information provided by the passed request. If the operation was
36    /// successful the url and a buffer that contains the schema information
37    /// is returned in `Ok(Some((url, buffer)))`. If the request could not be
38    /// resolved `Ok(None)` is returned.
39    ///
40    /// # Errors
41    ///
42    /// May return any error if resolving the schema information was not
43    /// successful.
44    fn resolve(&mut self, req: &ResolveRequest)
45        -> Result<Option<(Url, Self::Buffer)>, Self::Error>;
46}
47
48/// Contains information about the requested resolve action.
49#[must_use]
50#[derive(Debug)]
51pub struct ResolveRequest {
52    /// Location of the requested schema.
53    pub requested_location: String,
54
55    /// Namespace of the requested schema.
56    pub requested_ns: Option<Namespace>,
57
58    /// Location of the current processed schema.
59    pub current_location: Option<Url>,
60
61    /// Namespace of the current processed schema.
62    pub current_ns: Option<Namespace>,
63}
64
65impl ResolveRequest {
66    /// Create a new [`ResolveRequest`] instance from the passed `requested_location`.
67    pub fn new<X: Into<String>>(requested_location: X) -> Self {
68        Self {
69            requested_location: requested_location.into(),
70            requested_ns: None,
71
72            current_location: None,
73            current_ns: None,
74        }
75    }
76
77    /// Set the `requested_ns` field of this [`ResolveRequest`] instance.
78    pub fn requested_ns(mut self, ns: Namespace) -> Self {
79        self.requested_ns = Some(ns);
80
81        self
82    }
83
84    /// Set the `current_ns` field of this [`ResolveRequest`] instance.
85    pub fn current_ns(mut self, ns: Namespace) -> Self {
86        self.current_ns = Some(ns);
87
88        self
89    }
90
91    /// Set the `current_location` field of this [`ResolveRequest`] instance.
92    pub fn current_location<X: Into<Url>>(mut self, location: X) -> Self {
93        self.current_location = Some(location.into());
94
95        self
96    }
97}
98
99impl Display for ResolveRequest {
100    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
101        write!(f, "Location={}", self.requested_location)?;
102
103        if let Some(ns) = &self.requested_ns {
104            write!(f, "({})", ns)?;
105        }
106
107        if let Some(current) = &self.current_location {
108            write!(f, "Current={}", current)?;
109        }
110
111        if let Some(current_ns) = &self.current_ns {
112            write!(f, "({})", current_ns)?;
113        }
114
115        Ok(())
116    }
117}