xsd_parser/parser/resolver/
many_resolver.rs

1use std::error::Error as StdError;
2use std::io::BufRead;
3
4use anyhow::Error;
5use url::Url;
6
7use super::{ResolveRequest, Resolver};
8
9/// Implements a [`Resolver`] that can combines multiple different other resolvers
10/// into one single resolver.
11#[derive(Default, Debug)]
12pub struct ManyResolver {
13    resolvers: Vec<Box<dyn Resolver<Buffer = BoxedBuffer, Error = Error>>>,
14}
15
16type BoxedBuffer = Box<dyn BufRead + 'static>;
17
18#[derive(Debug)]
19#[must_use]
20struct MappedResolver<T>(T);
21
22impl ManyResolver {
23    /// Create a new empty [`ManyResolver`] instance.
24    #[must_use]
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Add a `resolver` to this [`ManyResolver`].
30    #[must_use]
31    pub fn add_resolver<R>(mut self, resolver: R) -> Self
32    where
33        R: Resolver + 'static,
34        R::Buffer: BufRead + 'static,
35        R::Error: StdError + Send + Sync + 'static,
36    {
37        self.resolvers.push(Box::new(MappedResolver(resolver)));
38
39        self
40    }
41}
42
43impl Resolver for ManyResolver {
44    type Buffer = BoxedBuffer;
45    type Error = Error;
46
47    fn resolve(
48        &mut self,
49        req: &ResolveRequest,
50    ) -> Result<Option<(Url, Self::Buffer)>, Self::Error> {
51        for resolver in self.resolvers.iter_mut() {
52            if let Some((location, buffer)) = resolver.resolve(req)? {
53                return Ok(Some((location, buffer)));
54            }
55        }
56
57        Ok(None)
58    }
59}
60
61/* MappedResolver */
62
63impl<R> Resolver for MappedResolver<R>
64where
65    R: Resolver + 'static,
66    R::Buffer: BufRead + 'static,
67    R::Error: StdError + Send + Sync + 'static,
68{
69    type Buffer = BoxedBuffer;
70    type Error = Error;
71
72    fn resolve(
73        &mut self,
74        req: &ResolveRequest,
75    ) -> Result<Option<(Url, Self::Buffer)>, Self::Error> {
76        match self.0.resolve(req) {
77            Ok(Some((location, buffer))) => Ok(Some((location, Box::new(buffer)))),
78            Ok(None) => Ok(None),
79            Err(error) => Err(Error::from(error)),
80        }
81    }
82}