1use anyhow::{Context, Result};
2use tera::Tera;
3use toml::map::Map;
4use toml::Value;
5
6pub fn render_template(template_str: &str, vars: &Map<String, Value>) -> Result<String> {
8 let mut tera = Tera::default();
9 tera.add_raw_template("__dotm_template", template_str)
10 .context("failed to parse template")?;
11
12 let context = toml_map_to_tera_context(vars);
13
14 tera.render("__dotm_template", &context)
15 .context("failed to render template")
16}
17
18fn toml_map_to_tera_context(vars: &Map<String, Value>) -> tera::Context {
19 let mut context = tera::Context::new();
20 for (key, value) in vars {
21 context.insert(key, &toml_value_to_json(value));
22 }
23 context
24}
25
26fn toml_value_to_json(value: &Value) -> serde_json::Value {
27 match value {
28 Value::String(s) => serde_json::Value::String(s.clone()),
29 Value::Integer(i) => serde_json::json!(*i),
30 Value::Float(f) => serde_json::json!(*f),
31 Value::Boolean(b) => serde_json::Value::Bool(*b),
32 Value::Datetime(dt) => serde_json::Value::String(dt.to_string()),
33 Value::Array(arr) => serde_json::Value::Array(arr.iter().map(toml_value_to_json).collect()),
34 Value::Table(table) => {
35 let map: serde_json::Map<String, serde_json::Value> =
36 table.iter().map(|(k, v)| (k.clone(), toml_value_to_json(v))).collect();
37 serde_json::Value::Object(map)
38 }
39 }
40}