Skip to main content

horto_os_ui_shared/kits/
template.rs

1//! Render and write embedded template files into host paths.
2
3use std::collections::BTreeMap;
4
5/// Replace `{{VAR}}` placeholders using the provided map.
6///
7/// # Examples
8///
9/// ```
10/// use horto_os_ui_shared::kits::template;
11/// use std::collections::BTreeMap;
12///
13/// let mut vars = BTreeMap::new();
14/// vars.insert("MY_HOSTNAME".into(), "box1".into());
15/// assert_eq!(template::render("host={{MY_HOSTNAME}}", &vars), "host=box1");
16/// ```
17#[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/// Return true when `{{UPPER_SNAKE}}` placeholders remain.
28///
29/// # Examples
30///
31/// ```
32/// use horto_os_ui_shared::kits::template;
33///
34/// assert!(template::has_unreplaced_placeholders("x={{FOO}}"));
35/// assert!(!template::has_unreplaced_placeholders("x=box1"));
36/// ```
37#[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}