Files
natter/src/context/dependency_manager.rs
2025-02-22 17:28:24 -05:00

85 lines
2.3 KiB
Rust

use std::path::Path;
use std::path::PathBuf;
use crate::error::CustomError;
use super::dependency::Dependency;
pub(crate) type RefDependencyManager = std::sync::Arc<std::sync::Mutex<DependencyManager>>;
#[derive(Debug)]
pub(crate) struct DependencyManager {
/// A stack of paths for the files being visited.
///
/// The last entry is the current file being processed. This can be used for handling relative-path links.
file_stack: Vec<PathBuf>,
dependencies: Vec<Dependency>,
}
impl DependencyManager {
pub(crate) fn new() -> Self {
DependencyManager {
file_stack: Vec::new(),
dependencies: Vec::new(),
}
}
pub(crate) fn push_file<P>(&mut self, path: P) -> Result<(), CustomError>
where
P: Into<PathBuf>,
{
self.file_stack.push(path.into());
Ok(())
}
pub(crate) fn pop_file(&mut self) -> Result<(), CustomError> {
self.file_stack
.pop()
.expect("Popped more files off the dependency manager file stack than exist.");
Ok(())
}
pub(crate) fn get_current_folder(&self) -> Result<&Path, CustomError> {
Ok(self
.file_stack
.last()
.ok_or("No current file")?
.parent()
.ok_or("Current file was not in a directory")?)
}
pub(crate) fn mark_file_for_copying<P>(&mut self, path: P) -> Result<(), CustomError>
where
P: Into<PathBuf>,
{
self.dependencies.push(Dependency::StaticFile {
absolute_path: path.into(),
});
Ok(())
}
/// Return the dependencies and forget about them.
pub(crate) fn take_dependencies(&mut self) -> Vec<Dependency> {
let mut dependencies = Vec::new();
std::mem::swap(&mut self.dependencies, &mut dependencies);
dependencies
}
pub(crate) fn include_css<N>(&mut self, name: N) -> Result<(), CustomError>
where
std::string::String: From<N>,
{
self.dependencies
.push(Dependency::CssFile { name: name.into() });
Ok(())
}
pub(crate) fn list_css(&self) -> Result<impl Iterator<Item = &String>, CustomError> {
Ok(self.dependencies.iter().filter_map(|dep| match dep {
Dependency::CssFile { name } => Some(name),
_ => None,
}))
}
}