use super::*;
struct IncludeError
{
path: PathBuf,
inner: StdError
}
impl std::fmt::Debug for IncludeError
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
write!(f, "While including path: {:?}", self.path)
}
}
impl std::fmt::Display for IncludeError
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
<Self as std::fmt::Debug>::fmt(self, f)
}
}
impl std::error::Error for IncludeError
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)>
{
Some(self.inner.as_ref())
}
}
#[derive(Default)]
pub struct FileLoader
{
loader: Loader,
visited: HashSet<PathBuf>
}
impl FileLoader
{
pub fn load(&mut self, path: impl AsRef<Path>) -> StdResult
{
self.load_single(path)?;
loop
{
let to_include = self.loader
.to_include()
.difference(&self.visited)
.cloned()
.collect::<HashSet<PathBuf>>();
if to_include.len() == 0
{
break;
}
for path in to_include
{
self.load_single(&path)
.map_err(|inner| IncludeError {
path: path.to_owned(), inner
})?;
}
}
Ok(())
}
fn load_single(&mut self, path_ref: impl AsRef<Path>) -> StdResult
{
let path = path_ref.as_ref().canonicalize()?;
let to_load = std::fs::read_to_string(&path)?;
let dir = path.parent().expect("Expected file path to have parent");
self.loader.add_document(&to_load, &dir)?;
self.visited.insert(path.to_owned());
Ok(())
}
pub fn inner(&self) -> &Loader { &self.loader }
pub fn into_inner(self) -> Loader { self.loader }
}