xsd_parser/parser/resolver/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Defines the [`Resolver`] trait and different resolver implementations.

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 crate::schema::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;

/// Trait that defines a so called resolver that can be used to load schema
/// information from different sources.
pub trait Resolver: Debug {
    /// Buffer that contains the data of the resolved schema.
    type Buffer;

    /// Error that is returned by the resolver.
    type Error: Display;

    /// Try to resolve the schema information from the passed request.
    ///
    /// This methods tries to resolve the schema information by using the
    /// information provided by the passed request. If the operation was
    /// successful the url and a buffer that contains the schema information
    /// is returned in `Ok(Some((url, buffer)))`. If the request could not be
    /// resolved `Ok(None)` is returned.
    ///
    /// # Errors
    ///
    /// May return any error if resolving the schema information was not
    /// successful.
    fn resolve(&mut self, req: &ResolveRequest)
        -> Result<Option<(Url, Self::Buffer)>, Self::Error>;
}

/// Contains information about the requested resolve action.
#[must_use]
#[derive(Debug)]
pub struct ResolveRequest {
    /// Location of the requested schema.
    pub requested_location: Url,

    /// Namespace of the requested schema.
    pub requested_ns: Option<Namespace>,

    /// Location of the current processed schema.
    pub current_location: Option<Url>,

    /// Namespace of the current processed schema.
    pub current_ns: Option<Namespace>,
}

impl ResolveRequest {
    /// Create a new [`ResolveRequest`] instance from the passed `requested_location`.
    pub fn new<X: Into<Url>>(requested_location: X) -> Self {
        Self {
            requested_location: requested_location.into(),
            requested_ns: None,

            current_location: None,
            current_ns: None,
        }
    }

    /// Set the `requested_ns` field of this [`ResolveRequest`] instance.
    pub fn requested_ns(mut self, ns: Namespace) -> Self {
        self.requested_ns = Some(ns);

        self
    }

    /// Set the `current_ns` field of this [`ResolveRequest`] instance.
    pub fn current_ns(mut self, ns: Namespace) -> Self {
        self.current_ns = Some(ns);

        self
    }

    /// Set the `current_location` field of this [`ResolveRequest`] instance.
    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, ", Namespace={}", ns)?;
        }

        Ok(())
    }
}