1use std::{2 any::Any,3 fs,4 io::Read,5 path::{Path, PathBuf},6};78use fs::File;9use jrsonnet_parser::SourcePath;1011use crate::{12 error::{Error::*, Result},13 throw,14};151617pub trait ImportResolver {18 19 20 21 fn resolve_file_relative(&self, from: &Path, path: &str) -> Result<SourcePath>;2223 24 25 26 fn load_file_contents(&self, resolved: &SourcePath) -> Result<Vec<u8>>;2728 29 30 31 32 33 unsafe fn as_any(&self) -> &dyn Any;34}353637pub struct DummyImportResolver;38impl ImportResolver for DummyImportResolver {39 fn resolve_file_relative(&self, from: &Path, path: &str) -> Result<SourcePath> {40 throw!(ImportNotSupported(from.into(), path.into()))41 }4243 fn load_file_contents(&self, _resolved: &SourcePath) -> Result<Vec<u8>> {44 panic!("dummy resolver can't load any file")45 }4647 unsafe fn as_any(&self) -> &dyn Any {48 panic!("`as_any(&self)` is not supported by dummy resolver")49 }50}51#[allow(clippy::use_self)]52impl Default for Box<dyn ImportResolver> {53 fn default() -> Self {54 Box::new(DummyImportResolver)55 }56}575859#[derive(Default)]60pub struct FileImportResolver {61 62 63 pub library_paths: Vec<PathBuf>,64}65impl ImportResolver for FileImportResolver {66 fn resolve_file_relative(&self, from: &Path, path: &str) -> Result<SourcePath> {67 let mut direct = from.to_path_buf();68 direct.push(path);69 if direct.exists() {70 Ok(SourcePath::Path(71 direct.canonicalize().map_err(|e| ImportIo(e.to_string()))?,72 ))73 } else {74 for library_path in &self.library_paths {75 let mut cloned = library_path.clone();76 cloned.push(path);77 if cloned.exists() {78 return Ok(SourcePath::Path(79 cloned.canonicalize().map_err(|e| ImportIo(e.to_string()))?,80 ));81 }82 }83 throw!(ImportFileNotFound(from.to_owned(), path.to_owned()))84 }85 }8687 fn load_file_contents(&self, id: &SourcePath) -> Result<Vec<u8>> {88 let path = match id {89 SourcePath::Path(path) => path,90 _ => {91 panic!("this resolver can only resolve to path")92 }93 };94 let mut file = File::open(path).map_err(|_e| ResolvedFileNotFound(id.clone()))?;95 let mut out = Vec::new();96 file.read_to_end(&mut out)97 .map_err(|e| ImportIo(e.to_string()))?;98 Ok(out)99 }100 unsafe fn as_any(&self) -> &dyn Any {101 panic!("this resolver can't be used as any")102 }103}