Add proper impl for templating

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-06 12:56:16 +01:00
parent 1ee7611981
commit 4470af3926
5 changed files with 85 additions and 27 deletions

View file

@ -5,16 +5,36 @@ use displaydoc::Display;
use serde::Serialize;
use thiserror::Error;
use crate::emit::Instruction;
use crate::input::TempleInput;
pub mod ast;
pub mod emit;
pub mod eval;
pub mod parser;
mod input;
pub mod parser;
#[derive(Debug, Error, Display)]
pub enum TempleError {
/// Could not parse the given template
ParseError {},
ParseError {
#[from]
source: parser::ParseFailure,
},
/// Invalid Template
AstError {
#[from]
source: ast::AstFailure,
},
/// An error occurred while evaluating
EvaluationError {
#[from]
source: eval::EvaluationError,
},
/// The template '{0}' could not be found
UnknownTemplate(String),
}
pub struct Temple {
@ -37,17 +57,41 @@ impl Temple {
pub fn add_template(
&mut self,
name: impl Into<String>,
value: impl AsRef<str>,
value: impl Into<TempleInput>,
) -> Result<(), TempleError> {
let source = value.into();
let parse = parser::parse(source.clone())?;
let ast = ast::parse(parse.tokens())?;
let instructions = emit::emit_machine(ast);
self.templates.insert(
name.into(),
Template {
source,
instructions,
},
);
Ok(())
}
fn render(&self, arg: &str, ctx: &Context) -> Result<String, TempleError> {
Ok(String::new())
pub fn render(&self, name: &str, ctx: &Context) -> Result<String, TempleError> {
let template = self
.templates
.get(name)
.ok_or_else(|| TempleError::UnknownTemplate(name.to_string()))?;
let res = eval::execute(&template.instructions, ctx)?;
Ok(res)
}
}
struct Template {}
struct Template {
source: TempleInput,
instructions: Vec<Instruction>,
}
pub struct Context {
values: BTreeMap<String, serde_json::Value>,
@ -155,6 +199,6 @@ mod tests {
let rendered = temp.render("base", &ctx).unwrap();
insta::assert_snapshot!(rendered, @"")
insta::assert_snapshot!(rendered, @"Hello World")
}
}