extern crate alloc;
use alloc::rc::Rc;
use std::{
collections::HashMap,
fs::{create_dir_all, File},
io::{self, ErrorKind, Write},
path::{Path, PathBuf},
};
use crate::HtmlError;
#[derive(Debug)]
pub struct TemplateContext {
pub input_path: Rc<PathBuf>,
pub output_path: Rc<PathBuf>,
pub file: File,
pub other_files: HashMap<Rc<PathBuf>, File>,
pub variables: HashMap<String, String>,
pub dependencies: Vec<Rc<PathBuf>>,
}
impl TemplateContext {
fn inner_write_all(&mut self, content: &[u8]) -> Result<(), io::Error> {
self.file.write_all(content)?;
for file in self.other_files.values_mut() {
file.write_all(content)?;
}
Ok(())
}
pub fn write_all(&mut self, content: &[u8]) -> Result<(), HtmlError> {
match self.inner_write_all(content) {
Err(error) if matches!(error.kind(), ErrorKind::NotFound) => {
Err(HtmlError::FileNotFound { path: "".into() })
}
_ => Ok(()),
}
}
pub fn write_char(&mut self, char: char) -> Result<(), io::Error> {
write!(self.file, "{char}")?;
for file in self.other_files.values_mut() {
write!(file, "{char}")?;
}
Ok(())
}
pub fn create_output_path(&self, path: PathBuf) -> PathBuf {
self.output_path.clone().join(path)
}
pub fn create_input_path(&self, path: impl AsRef<Path>) -> PathBuf {
self.input_path.join(path.as_ref())
}
pub fn push_output(&mut self, path: &PathBuf) -> Result<(), io::Error> {
let Some(parent_path) = path.parent() else {
return Ok(());
};
create_dir_all(parent_path)?;
if let Ok(file) = File::options()
.create(true)
.write(true)
.truncate(true)
.open(path)
{
self.other_files.insert(Rc::new(path.clone()), file);
}
Ok(())
}
pub fn is_debug(&self) -> bool {
if let Some(debug) = self.variables.get("is-debug") {
return debug == "true";
}
false
}
pub fn should_remove_whitespaces(&self) -> bool {
if let Some(should_remove_whitepaces) = self.variables.get("should-remove-whitespaces") {
return should_remove_whitepaces == "true";
}
false
}
pub fn should_remove_comments(&self) -> bool {
if let Some(should_remove_whitepaces) = self.variables.get("should-remove-comments") {
return should_remove_whitepaces == "true";
}
false
}
pub fn remove_output_by_path(&mut self, path: &PathBuf) {
self.other_files.remove(path);
}
}