polysite/compiler/
template.rs1use crate::{builder::metadata::BODY_META, *};
2use serde_json::Value;
3use std::sync::Arc;
4use tera::Tera;
5
6#[derive(Clone)]
8pub struct TemplateEngine {
9 tera: Tera,
10}
11impl TemplateEngine {
12 pub fn new(template_dir: impl AsRef<str>) -> Result<Self, Error> {
13 let tera = tera::Tera::new(template_dir.as_ref()).map_err(|err| Error::user_error(err))?;
14 Ok(Self { tera })
15 }
16
17 pub fn get(self) -> Arc<Self> {
18 Arc::new(self)
19 }
20
21 pub async fn render(
23 &self,
24 template: impl AsRef<str>,
25 metadata: &Metadata,
26 ) -> Result<String, Error> {
27 let tera_ctx = tera::Context::from_serialize(metadata.read_lock().await)
28 .map_err(|err| Error::user_error(err))?;
29 self.tera
30 .render(template.as_ref(), &tera_ctx)
31 .map_err(|err| Error::user_error(err))
32 }
33}
34
35#[derive(Clone)]
37pub struct TemplateRenderer {
38 engine: TemplateEngine,
39 template: String,
40}
41impl TemplateRenderer {
42 pub fn new(engine: TemplateEngine, template: impl AsRef<str>) -> Self {
43 let template = template.as_ref().to_owned();
44 Self { engine, template }
45 }
46}
47impl Compiler for TemplateRenderer {
48 #[tracing::instrument(skip(self, ctx))]
49 fn next_step(&mut self, mut ctx: Context) -> CompilerReturn {
50 let engine = self.engine.clone();
51 let template = self.template.clone();
52 compile!({
53 let metadata = ctx.metadata();
54 let body = engine.render(&template, &metadata).await?;
55 ctx.metadata_mut()
56 .insert_local(BODY_META.to_owned(), Value::String(body));
57 Ok(CompileStep::Completed(ctx))
58 })
59 }
60}