xsd_parser/pipeline/parser/resolver/
file_resolver.rs

1use std::ffi::OsStr;
2use std::fs::File;
3use std::io::{BufReader, Error};
4
5use url::Url;
6
7use super::{strip_name_ext, ResolveRequest, ResolveResult, Resolver};
8
9/// Implements a [`Resolver`] that can be used to load local files.
10#[must_use]
11#[derive(Default, Debug)]
12pub struct FileResolver;
13
14impl FileResolver {
15    /// Create a new [`FileResolver`] instance.
16    pub fn new() -> Self {
17        Self
18    }
19}
20
21impl Resolver for FileResolver {
22    type Buffer = BufReader<File>;
23    type Error = Error;
24
25    fn resolve(&mut self, req: &ResolveRequest) -> ResolveResult<Self> {
26        let url = if let Some(current) = &req.current_location {
27            current.join(&req.requested_location)
28        } else {
29            Url::parse(&req.requested_location)
30        };
31
32        let Ok(url) = url else {
33            return Ok(None);
34        };
35
36        let Ok(path) = url.to_file_path() else {
37            return Ok(None);
38        };
39
40        let file = File::open(&path)?;
41        let buffer = BufReader::new(file);
42
43        let name = path
44            .iter()
45            .next_back()
46            .and_then(OsStr::to_str)
47            .map(strip_name_ext)
48            .map(ToOwned::to_owned);
49
50        Ok(Some((name, url, buffer)))
51    }
52}