From 0dede943e976be6c8e8f28a2067e2e5dedd39652 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 8 Jun 2021 00:25:36 +0100 Subject: [PATCH] specs: Add a templating facility for game specs Signed-off-by: Ian Jackson --- src/bundles.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/bundles.rs b/src/bundles.rs index 9fd4477a..d95d8f85 100644 --- a/src/bundles.rs +++ b/src/bundles.rs @@ -900,7 +900,36 @@ pub fn load_spec_to_read(ig: &Instance, spec_name: &str) -> String { ErrorKind::UnexpectedEof => ME::BadBundle(e.to_string()), _ => e_f(e), })?; - buf + + if ! buf.starts_with("{#") { return buf } + + (||{ + let templates: Vec<(&str, Cow)> = match buf.rfind("\n{% endmacro") { + None => vec![ ("spec", buf.into()) ], + Some(endm_base) => { + let endm_sol = endm_base + 1; + let endm_end = endm_sol + 1 + + buf[endm_sol..].find('\n') + .ok_or_else(|| anyhow!("endmacro line not terminated"))?; + let mac_data = &buf[0..endm_end]; + let spec_data = + r#"{% import "m" as m %}"#.to_string() + + &"\n".repeat(mac_data.matches('\n').count()) + + &buf[endm_end..]; + vec![ ("m", mac_data .into()), + ("spec", spec_data.into()) ] + }, + }; + let mut tera = tera_standalone::Tera::default(); + tera.add_raw_templates(templates).context("load")?; + let mut out: Vec = vec![]; + tera.render_to("spec", &default(), &mut out).context("render")?; + let out = String::from_utf8(out).context("reparse as utf-8")?; + Ok::<_,AE>(out) + })() + .map_err(|ae| ME::BadBundle( + format!("process spec as Tera template: {}", ae.d()) + ))? } let spec_leaf = format!("{}.game.toml", spec_name); -- 2.30.2