use std::collections::HashMap; use std::sync::Arc; use minijinja::Environment; use tokio::sync::RwLock; /// Renders email templates using MiniJinja. pub struct EmailTemplates { env: Arc>>, } impl std::fmt::Debug for EmailTemplates { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("EmailTemplates").finish() } } impl EmailTemplates { pub fn new() -> Self { Self { env: Arc::new(RwLock::new(Environment::new())) } } /// Add a template from a string. pub async fn add_template(&self, name: &str, template: &str) -> Result<(), anyhow::Error> { let mut env = self.env.write().await; env.add_template_owned(name.to_string(), template.to_string())?; Ok(()) } /// Render a named template with the given context. pub async fn render( &self, name: &str, ctx: &HashMap, ) -> Result { let env = self.env.read().await; let tmpl = env.get_template(name)?; let result = tmpl.render(ctx)?; Ok(result) } } impl Default for EmailTemplates { fn default() -> Self { Self::new() } }