stawege-html-plugin 0.1.2

HTML template engine plugin for Stawege.
Documentation
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);
    }
}