use std::sync::Arc; use minijinja::Environment; use pathdiff::diff_paths; use tokio::sync::Mutex; use tracing::info; #[derive(Clone)] pub struct Templates { env: Arc>>, } pub type Error = Box; impl Templates { pub fn empty() -> Self { let env = Arc::new(Mutex::new(Environment::new())); Self { env } } pub async fn try_load() -> Result { let mut result = Self::empty(); result.load_env().await?; Ok(result) } pub async fn start_watcher(&mut self) { info!("TODO: Implement template watcher"); } pub async fn load_env(&mut self) -> Result<(), Error> { info!("Loading templates..."); for d in walkdir::WalkDir::new("src/templates") { match d { Ok(d) => { if d.file_type().is_dir() { continue; } let filename: String = diff_paths(d.path(), "src/templates") .unwrap() .to_string_lossy() .into_owned(); info!("Loading template {filename:#?} ({d:#?})"); self.env .clone() .lock() .await .add_template_owned(filename, std::fs::read_to_string(d.path())?)?; } Err(_) => todo!(), } } info!("Done loading templates!"); Ok(()) } pub async fn render( &self, template_name: &str, context: S, ) -> Result { self.env .lock() .await .get_template(template_name)? .render(context) } }