use crate::Error;
use crate::template::Assets;
use std::collections::HashMap;
use std::io::Read;
use tera::{Context, Tera};
const GLOBAL_PREFIX: &str = "_global/";
pub struct TemplateEngine {
assets: Assets,
tera: Tera,
globals: HashMap<String, String>,
}
impl TemplateEngine {
pub fn from_bytes(bytes: impl Read) -> Result<Self, Error> {
let assets = Assets::from_reader(bytes).expect("Assets must exist");
let mut tera = Tera::default();
let mut globals = HashMap::new();
for path in assets.list() {
if let Some(rest) = path.strip_prefix(GLOBAL_PREFIX) {
let var_name = format!("_{}", rest.trim_end_matches(".cs").replace('/', "_"));
let content = assets.get_string(path)?;
globals.insert(var_name, content);
}
}
tera.add_raw_templates(assets.list().filter(|x| !x.starts_with(GLOBAL_PREFIX)).map(|x| (x, assets.get_string(x).unwrap())))?;
Ok(Self { assets, tera, globals })
}
pub fn get(&self, path: impl AsRef<str>) -> Result<String, Error> {
let x = self.assets.get_string(path)?;
Ok(x)
}
pub fn render(&self, path: impl AsRef<str>, context: &Context) -> Result<String, Error> {
let mut ctx = context.clone();
for (key, value) in &self.globals {
ctx.insert(key.as_str(), value);
}
let rendered = self.tera.render(path.as_ref(), &ctx)?;
Ok(rendered)
}
}