use crate::Result;
use handlebars::Handlebars;
use serde_json::Value;
use std::sync::{Arc, LazyLock};
static HANDLEBARS: LazyLock<Arc<Handlebars>> = LazyLock::new(|| {
let mut handlebars = Handlebars::new();
handlebars.register_escape_fn(|s| s.to_string());
Arc::new(handlebars)
});
pub fn hbs_render(hbs_tmpl: &str, data_root: &Value) -> Result<String> {
let handlebars = &*HANDLEBARS;
let res = handlebars.render_template(hbs_tmpl, &data_root)?;
Ok(res)
}
#[cfg(test)]
mod tests {
type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>;
use crate::_test_support::assert_contains;
use crate::runtime::Runtime;
use crate::support::hbs::hbs_render;
use serde_json::json;
#[tokio::test]
async fn test_hbs_with_lua_ok() -> Result<()> {
let runtime = Runtime::new_test_runtime_sandbox_01()?;
let script = r#"
local file1 = aip.file.load("file-01.txt")
local file2 = aip.file.load("agent-script/agent-before-all.aip")
return {file1,file2} -- Return an array of File structs
"#;
let tmpl = r#"
The files are:
{{#each data}}
- {{this.path}}
{{/each}}
"#;
let lua_engine = runtime.new_lua_engine_without_ctx_test_only()?;
let data = lua_engine.eval(script, None, None)?;
let data = serde_json::to_value(data)?;
let value = json!({
"data": data
});
let res = hbs_render(tmpl, &value)?;
assert_contains(&res, "- file-01.txt");
assert_contains(&res, "- agent-script/agent-before-all.aip");
Ok(())
}
}