horto_os_ui_shared/kits/
template.rs1use std::collections::BTreeMap;
4
5#[must_use]
18pub fn render(template: &str, vars: &BTreeMap<String, String>) -> String {
19 let mut out = template.to_string();
20 for (key, value) in vars {
21 let needle = format!("{{{{{key}}}}}");
22 out = out.replace(&needle, value);
23 }
24 out
25}
26
27#[must_use]
38pub fn has_unreplaced_placeholders(text: &str) -> bool {
39 let bytes = text.as_bytes();
40 let mut i = 0;
41 while i + 1 < bytes.len() {
42 if bytes[i] == b'{' && bytes[i + 1] == b'{' {
43 if let Some(end) = text[i + 2..].find("}}") {
44 let name = &text[i + 2..i + 2 + end];
45 if name
46 .chars()
47 .all(|c| c.is_ascii_uppercase() || c.is_ascii_digit() || c == '_')
48 && !name.is_empty()
49 {
50 return true;
51 }
52 }
53 }
54 i += 1;
55 }
56 false
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use std::collections::BTreeMap;
63
64 #[test]
65 fn render_replaces_vars() {
66 let mut vars = BTreeMap::new();
67 vars.insert("MY_HOSTNAME".into(), "box1".into());
68 let out = render("host={{MY_HOSTNAME}}", &vars);
69 assert_eq!(out, "host=box1");
70 }
71
72 #[test]
73 fn detects_placeholders() {
74 assert!(has_unreplaced_placeholders("x={{FOO}} y"));
75 assert!(!has_unreplaced_placeholders("x=box1"));
76 }
77}