Skip to main content

nargo_template/
manager.rs

1#![warn(missing_docs)]
2
3use std::{collections::HashMap, path::Path, path::PathBuf};
4
5use super::engine::TemplateEngine;
6use super::renderers::TemplateRenderer;
7
8/// 模板管理器
9pub struct TemplateManager {
10    renderers: HashMap<TemplateEngine, Box<dyn TemplateRenderer>>,
11    template_dirs: Vec<PathBuf>,
12}
13
14impl TemplateManager {
15    /// 创建新的模板管理器
16    pub fn new() -> Self {
17        let mut renderers = HashMap::new();
18
19        #[cfg(feature = "jinja")]
20        {
21            renderers.insert(TemplateEngine::Jinja2, Box::new(super::renderers::jinja::Jinja2Renderer::new()) as Box<dyn TemplateRenderer>);
22        }
23
24        #[cfg(feature = "dejavu")]
25        {
26            // 注册 DejaVu 模板引擎,使用默认配置
27            renderers.insert(TemplateEngine::DejaVu, Box::new(super::renderers::dejavu::DejaVuRenderer::new()) as Box<dyn TemplateRenderer>);
28        }
29
30        #[cfg(feature = "liquid")]
31        {
32            // 注册 Liquid 模板引擎
33            renderers.insert(TemplateEngine::Liquid, Box::new(super::renderers::liquid::LiquidRenderer::new()) as Box<dyn TemplateRenderer>);
34        }
35
36        Self { renderers, template_dirs: Vec::new() }
37    }
38
39    /// 注册自定义模板渲染器
40    pub fn register_renderer(&mut self, engine: TemplateEngine, renderer: Box<dyn TemplateRenderer>) {
41        self.renderers.insert(engine, renderer);
42    }
43
44    /// 注册模板
45    pub fn register_template(&mut self, engine: TemplateEngine, name: &str, content: &str) -> crate::TemplateResult<()> {
46        let renderer = self.renderers.get_mut(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
47        renderer.register_template(name, content)
48    }
49
50    /// 注册模板文件
51    pub fn register_template_file(&mut self, engine: TemplateEngine, name: &str, path: &Path) -> crate::TemplateResult<()> {
52        let renderer = self.renderers.get_mut(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
53        renderer.register_template_file(name, path)
54    }
55
56    /// 添加模板目录
57    pub fn add_template_dir<P: AsRef<Path>>(&mut self, dir: P) {
58        self.template_dirs.push(dir.as_ref().to_path_buf());
59    }
60
61    /// 从所有已注册的模板目录加载模板
62    pub fn load_templates(&mut self, engine: TemplateEngine) -> crate::TemplateResult<()> {
63        let ext = engine.default_extension();
64        let dirs: Vec<_> = self.template_dirs.clone();
65
66        if let Some(renderer) = self.renderers.get_mut(&engine) {
67            for dir in dirs {
68                if dir.exists() {
69                    renderer.register_templates_from_dir(dir.as_path(), Some(ext))?;
70                }
71            }
72        }
73        Ok(())
74    }
75
76    /// 使用指定引擎渲染模板
77    pub fn render(&self, engine: TemplateEngine, template_name: &str, context: &serde_json::Value) -> crate::TemplateResult<String> {
78        let renderer = self.renderers.get(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
79
80        renderer.render(template_name, context)
81    }
82
83    /// 异步渲染模板
84    pub async fn render_async(&self, engine: TemplateEngine, template_name: &str, context: &serde_json::Value) -> crate::TemplateResult<String> {
85        let renderer = self.renderers.get(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
86
87        renderer.render_async(template_name, context).await
88    }
89}
90
91impl Default for TemplateManager {
92    fn default() -> Self {
93        Self::new()
94    }
95}