#![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")]
{
renderers.insert(TemplateEngine::DejaVu, Box::new(super::renderers::dejavu::DejaVuRenderer::new()) as Box<dyn TemplateRenderer>);
}
#[cfg(feature = "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()
}
}