use crate::template::{ComposeSection, Theme};
use anyhow::{Context, bail};
use handlebars::Handlebars;
use serde_json::{Map, Value};
pub fn render_sections(
hbs: &Handlebars<'static>,
sections: &[ComposeSection],
theme: &Theme,
) -> anyhow::Result<Value> {
let mut body = Vec::new();
for (idx, section) in sections.iter().enumerate() {
if !hbs.has_template(§ion.primitive) {
bail!(
"primitive '{}' not found in section {}",
section.primitive,
idx
);
}
let context = build_section_context(§ion.data, theme);
let rendered = hbs
.render(§ion.primitive, &context)
.with_context(|| format!("rendering section {} ({})", idx, section.primitive))?;
let fixed = super::post_process::fix_trailing_commas(&rendered);
let fragment: Value = serde_json::from_str(&fixed)
.with_context(|| format!("parsing section {} output", idx))?;
body.push(fragment);
}
Ok(serde_json::json!({
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": body
}))
}
fn build_section_context(data: &Value, theme: &Theme) -> Value {
let mut ctx = match data {
Value::Object(map) => map.clone(),
_ => Map::new(),
};
let mut theme_obj = Map::new();
let mut tokens = Map::new();
for (key, value) in &theme.tokens {
tokens.insert(key.clone(), value.clone());
}
theme_obj.insert("tokens".to_string(), Value::Object(tokens));
ctx.insert("theme".to_string(), Value::Object(theme_obj));
Value::Object(ctx)
}