Skip to main content

cargo_image_runner/image/
template.rs

1use crate::core::error::Result;
2use std::collections::HashMap;
3
4/// Template processor for substituting variables in configuration files.
5pub struct TemplateProcessor;
6
7impl TemplateProcessor {
8    /// Process template variables in content.
9    ///
10    /// Supports both {{VAR}} and $VAR syntax.
11    pub fn process(content: &str, vars: &HashMap<String, String>) -> Result<String> {
12        let mut result = content.to_string();
13
14        // Process {{VAR}} syntax
15        for (key, value) in vars {
16            let placeholder = format!("{{{{{}}}}}", key);
17            result = result.replace(&placeholder, value);
18        }
19
20        // Process $VAR syntax
21        // This is a simple implementation - could be enhanced to handle ${VAR} etc.
22        for (key, value) in vars {
23            let placeholder = format!("${}", key);
24            result = result.replace(&placeholder, value);
25        }
26
27        Ok(result)
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn test_template_double_brace() {
37        let mut vars = HashMap::new();
38        vars.insert("NAME".to_string(), "test".to_string());
39        vars.insert("VALUE".to_string(), "123".to_string());
40
41        let content = "Hello {{NAME}}, value is {{VALUE}}";
42        let result = TemplateProcessor::process(content, &vars).unwrap();
43        assert_eq!(result, "Hello test, value is 123");
44    }
45
46    #[test]
47    fn test_template_dollar() {
48        let mut vars = HashMap::new();
49        vars.insert("VAR".to_string(), "substituted".to_string());
50
51        let content = "This is $VAR";
52        let result = TemplateProcessor::process(content, &vars).unwrap();
53        assert_eq!(result, "This is substituted");
54    }
55
56    #[test]
57    fn test_template_mixed() {
58        let mut vars = HashMap::new();
59        vars.insert("A".to_string(), "alpha".to_string());
60        vars.insert("B".to_string(), "beta".to_string());
61
62        let content = "{{A}} and $B";
63        let result = TemplateProcessor::process(content, &vars).unwrap();
64        assert_eq!(result, "alpha and beta");
65    }
66
67    #[test]
68    fn test_template_no_vars() {
69        let vars = HashMap::new();
70        let content = "Hello, world!";
71        let result = TemplateProcessor::process(content, &vars).unwrap();
72        assert_eq!(result, "Hello, world!");
73    }
74
75    #[test]
76    fn test_template_empty_content() {
77        let vars = HashMap::new();
78        let result = TemplateProcessor::process("", &vars).unwrap();
79        assert_eq!(result, "");
80    }
81
82    #[test]
83    fn test_template_unknown_var_preserved() {
84        let mut vars = HashMap::new();
85        vars.insert("KNOWN".to_string(), "value".to_string());
86
87        let content = "{{KNOWN}} and {{UNKNOWN}}";
88        let result = TemplateProcessor::process(content, &vars).unwrap();
89        assert_eq!(result, "value and {{UNKNOWN}}");
90    }
91
92    #[test]
93    fn test_template_repeated_var() {
94        let mut vars = HashMap::new();
95        vars.insert("X".to_string(), "42".to_string());
96
97        let content = "{{X}} + {{X}} = 2*{{X}}";
98        let result = TemplateProcessor::process(content, &vars).unwrap();
99        assert_eq!(result, "42 + 42 = 2*42");
100    }
101
102    #[test]
103    fn test_template_multiline() {
104        let mut vars = HashMap::new();
105        vars.insert("TIMEOUT".to_string(), "5".to_string());
106        vars.insert("EXECUTABLE_NAME".to_string(), "kernel.elf".to_string());
107        vars.insert("CMDLINE".to_string(), "quiet".to_string());
108
109        let content = "timeout: {{TIMEOUT}}\n\n/My Kernel\n    protocol: limine\n    kernel_path: boot():/boot/{{EXECUTABLE_NAME}}\n    cmdline: {{CMDLINE}}";
110        let result = TemplateProcessor::process(content, &vars).unwrap();
111        assert_eq!(
112            result,
113            "timeout: 5\n\n/My Kernel\n    protocol: limine\n    kernel_path: boot():/boot/kernel.elf\n    cmdline: quiet"
114        );
115    }
116}