nargo-template 0.0.1

Nargo template engine management
Documentation
#![warn(missing_docs)]

use std::{collections::HashMap, path::Path, path::PathBuf};

use super::engine::TemplateEngine;
use super::renderers::TemplateRenderer;

/// 模板管理器
pub struct TemplateManager {
    renderers: HashMap<TemplateEngine, Box<dyn TemplateRenderer>>,
    template_dirs: Vec<PathBuf>,
}

impl TemplateManager {
    /// 创建新的模板管理器
    pub fn new() -> Self {
        let mut renderers = HashMap::new();

        #[cfg(feature = "jinja")]
        {
            renderers.insert(TemplateEngine::Jinja2, Box::new(super::renderers::jinja::Jinja2Renderer::new()) as Box<dyn TemplateRenderer>);
        }

        #[cfg(feature = "dejavu")]
        {
            // 注册 DejaVu 模板引擎,使用默认配置
            renderers.insert(TemplateEngine::DejaVu, Box::new(super::renderers::dejavu::DejaVuRenderer::new()) as Box<dyn TemplateRenderer>);
        }

        #[cfg(feature = "liquid")]
        {
            // 注册 Liquid 模板引擎
            renderers.insert(TemplateEngine::Liquid, Box::new(super::renderers::liquid::LiquidRenderer::new()) as Box<dyn TemplateRenderer>);
        }

        Self { renderers, template_dirs: Vec::new() }
    }

    /// 注册自定义模板渲染器
    pub fn register_renderer(&mut self, engine: TemplateEngine, renderer: Box<dyn TemplateRenderer>) {
        self.renderers.insert(engine, renderer);
    }

    /// 注册模板
    pub fn register_template(&mut self, engine: TemplateEngine, name: &str, content: &str) -> crate::TemplateResult<()> {
        let renderer = self.renderers.get_mut(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
        renderer.register_template(name, content)
    }

    /// 注册模板文件
    pub fn register_template_file(&mut self, engine: TemplateEngine, name: &str, path: &Path) -> crate::TemplateResult<()> {
        let renderer = self.renderers.get_mut(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;
        renderer.register_template_file(name, path)
    }

    /// 添加模板目录
    pub fn add_template_dir<P: AsRef<Path>>(&mut self, dir: P) {
        self.template_dirs.push(dir.as_ref().to_path_buf());
    }

    /// 从所有已注册的模板目录加载模板
    pub fn load_templates(&mut self, engine: TemplateEngine) -> crate::TemplateResult<()> {
        let ext = engine.default_extension();
        let dirs: Vec<_> = self.template_dirs.clone();

        if let Some(renderer) = self.renderers.get_mut(&engine) {
            for dir in dirs {
                if dir.exists() {
                    renderer.register_templates_from_dir(dir.as_path(), Some(ext))?;
                }
            }
        }
        Ok(())
    }

    /// 使用指定引擎渲染模板
    pub fn render(&self, engine: TemplateEngine, template_name: &str, context: &serde_json::Value) -> crate::TemplateResult<String> {
        let renderer = self.renderers.get(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;

        renderer.render(template_name, context)
    }

    /// 异步渲染模板
    pub async fn render_async(&self, engine: TemplateEngine, template_name: &str, context: &serde_json::Value) -> crate::TemplateResult<String> {
        let renderer = self.renderers.get(&engine).ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, format!("Template engine '{:?}' not registered", engine)))?;

        renderer.render_async(template_name, context).await
    }
}

impl Default for TemplateManager {
    fn default() -> Self {
        Self::new()
    }
}