llm_config_templates/
engine.rs1use crate::{parser, Result, Template, TemplateError};
4use std::collections::HashMap;
5
6pub struct TemplateEngine {
8 templates: HashMap<String, Template>,
9}
10
11impl TemplateEngine {
12 pub fn new() -> Self {
14 Self {
15 templates: HashMap::new(),
16 }
17 }
18
19 pub fn register(&mut self, template: Template) {
21 self.templates.insert(template.name.clone(), template);
22 }
23
24 pub fn get(&self, name: &str) -> Option<&Template> {
26 self.templates.get(name)
27 }
28
29 pub fn remove(&mut self, name: &str) -> Option<Template> {
31 self.templates.remove(name)
32 }
33
34 pub fn render_template(
36 &self,
37 name: &str,
38 vars: &HashMap<String, String>,
39 ) -> Result<String> {
40 let template = self
41 .templates
42 .get(name)
43 .ok_or_else(|| TemplateError::InvalidTemplate(format!("Template not found: {}", name)))?;
44
45 template.render(vars)
46 }
47
48 pub fn render(&self, template_str: &str, vars: &HashMap<String, String>) -> Result<String> {
50 let tokens = parser::parse(template_str)?;
51 let mut result = String::new();
52
53 for token in tokens {
54 match token {
55 parser::Token::Literal(text) => result.push_str(&text),
56 parser::Token::Variable(var_name) => {
57 let value = vars
58 .get(&var_name)
59 .ok_or_else(|| TemplateError::VariableNotFound(var_name))?;
60 result.push_str(value);
61 }
62 }
63 }
64
65 Ok(result)
66 }
67
68 pub fn list_templates(&self) -> Vec<&str> {
70 self.templates.keys().map(|s| s.as_str()).collect()
71 }
72
73 pub fn count(&self) -> usize {
75 self.templates.len()
76 }
77}
78
79impl Default for TemplateEngine {
80 fn default() -> Self {
81 Self::new()
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_engine_creation() {
91 let engine = TemplateEngine::new();
92 assert_eq!(engine.count(), 0);
93 }
94
95 #[test]
96 fn test_register_template() {
97 let mut engine = TemplateEngine::new();
98 let template = Template::new("test", "Hello, {{name}}!").unwrap();
99
100 engine.register(template);
101 assert_eq!(engine.count(), 1);
102 }
103
104 #[test]
105 fn test_get_template() {
106 let mut engine = TemplateEngine::new();
107 let template = Template::new("test", "Hello, {{name}}!").unwrap();
108
109 engine.register(template);
110
111 let retrieved = engine.get("test");
112 assert!(retrieved.is_some());
113 assert_eq!(retrieved.unwrap().name, "test");
114 }
115
116 #[test]
117 fn test_remove_template() {
118 let mut engine = TemplateEngine::new();
119 let template = Template::new("test", "Hello, {{name}}!").unwrap();
120
121 engine.register(template);
122 assert_eq!(engine.count(), 1);
123
124 let removed = engine.remove("test");
125 assert!(removed.is_some());
126 assert_eq!(engine.count(), 0);
127 }
128
129 #[test]
130 fn test_render_template() {
131 let mut engine = TemplateEngine::new();
132 let template = Template::new("greeting", "Hello, {{name}}!").unwrap();
133 engine.register(template);
134
135 let mut vars = HashMap::new();
136 vars.insert("name".to_string(), "Alice".to_string());
137
138 let result = engine.render_template("greeting", &vars).unwrap();
139 assert_eq!(result, "Hello, Alice!");
140 }
141
142 #[test]
143 fn test_render_direct() {
144 let engine = TemplateEngine::new();
145
146 let mut vars = HashMap::new();
147 vars.insert("name".to_string(), "Bob".to_string());
148 vars.insert("age".to_string(), "30".to_string());
149
150 let result = engine
151 .render("Name: {{name}}, Age: {{age}}", &vars)
152 .unwrap();
153 assert_eq!(result, "Name: Bob, Age: 30");
154 }
155
156 #[test]
157 fn test_list_templates() {
158 let mut engine = TemplateEngine::new();
159 engine.register(Template::new("t1", "{{var1}}").unwrap());
160 engine.register(Template::new("t2", "{{var2}}").unwrap());
161 engine.register(Template::new("t3", "{{var3}}").unwrap());
162
163 let templates = engine.list_templates();
164 assert_eq!(templates.len(), 3);
165 assert!(templates.contains(&"t1"));
166 assert!(templates.contains(&"t2"));
167 assert!(templates.contains(&"t3"));
168 }
169
170 #[test]
171 fn test_template_not_found() {
172 let engine = TemplateEngine::new();
173 let vars = HashMap::new();
174
175 let result = engine.render_template("nonexistent", &vars);
176 assert!(result.is_err());
177 }
178
179 #[test]
180 fn test_variable_not_found() {
181 let engine = TemplateEngine::new();
182 let vars = HashMap::new();
183
184 let result = engine.render("Hello, {{name}}!", &vars);
185 assert!(result.is_err());
186 }
187}