use std::collections::HashMap;
pub fn loader_env(
template_dir: &str,
embedded: &'static HashMap<&'static str, &'static str>,
) -> minijinja::Environment<'static> {
let dir = (!template_dir.is_empty()).then(|| std::path::PathBuf::from(template_dir));
let mut env = minijinja::Environment::new();
env.set_loader(move |name| {
if let Some(dir) = &dir
&& let Ok(contents) = std::fs::read_to_string(dir.join(name))
{
return Ok(Some(contents));
}
Ok(embedded.get(name).map(|body| (*body).to_string()))
});
env
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::LazyLock;
static TABLE: LazyLock<HashMap<&'static str, &'static str>> =
LazyLock::new(|| HashMap::from([("a.j2", "embedded a"), ("b.j2", "embedded b")]));
#[test]
fn an_empty_directory_uses_the_embedded_default() {
let env = loader_env("", &TABLE);
assert_eq!(
env.get_template("a.j2").unwrap().render(()).unwrap(),
"embedded a"
);
}
#[test]
fn a_directory_file_beats_the_default_for_that_name_only() {
let dir = crate::testutil::TempDir::new("templating-loader");
std::fs::write(dir.as_ref().join("a.j2"), "from disk").unwrap();
let env = loader_env(dir.as_ref().to_str().unwrap(), &TABLE);
assert_eq!(
env.get_template("a.j2").unwrap().render(()).unwrap(),
"from disk"
);
assert_eq!(
env.get_template("b.j2").unwrap().render(()).unwrap(),
"embedded b"
);
}
#[test]
fn an_unknown_name_is_simply_not_found() {
let env = loader_env("", &TABLE);
assert!(env.get_template("nope.j2").is_err());
}
#[test]
fn a_missing_directory_falls_through_to_the_defaults() {
let env = loader_env("/nonexistent/acme-proxy-templates", &TABLE);
assert_eq!(
env.get_template("a.j2").unwrap().render(()).unwrap(),
"embedded a"
);
}
}