1use std::sync::Arc;
4use alun_core::Result;
5
6#[derive(Clone)]
8pub struct TemplateEngine {
9 env: Arc<minijinja::Environment<'static>>,
11}
12
13impl TemplateEngine {
14 pub fn new() -> Self {
16 Self { env: Arc::new(minijinja::Environment::new()) }
17 }
18
19 pub fn from_dir(dir: &str) -> Result<Self> {
21 let mut env = minijinja::Environment::new();
22 env.set_loader(minijinja::path_loader(dir));
23 Ok(Self { env: Arc::new(env) })
24 }
25
26 pub fn render<C: serde::Serialize>(&self, name: &str, ctx: &C) -> Result<String> {
32 let tmpl = self.env
33 .get_template(name)
34 .map_err(|e| alun_core::Error::Template(format!("模板加载失败 {}: {}", name, e)))?;
35 let ctx_val = minijinja::value::Value::from_serialize(ctx);
36 tmpl.render(&ctx_val)
37 .map_err(|e| alun_core::Error::Template(format!("模板渲染失败: {}", e)))
38 }
39
40 pub fn render_str<C: serde::Serialize>(&self, source: &str, ctx: &C) -> Result<String> {
42 let tmpl = self.env
43 .template_from_str(source)
44 .map_err(|e| alun_core::Error::Template(format!("模板编译失败: {}", e)))?;
45 let ctx_val = minijinja::value::Value::from_serialize(ctx);
46 tmpl.render(&ctx_val)
47 .map_err(|e| alun_core::Error::Template(format!("模板渲染失败: {}", e)))
48 }
49}
50
51impl Default for TemplateEngine {
52 fn default() -> Self { Self::new() }
53}