xsd_parser/pipeline/parser/resolver/
many_resolver.rs

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