quickstart_lib/template/
engine.rs1use handlebars::Handlebars;
7
8use super::{Result, TemplateError, TemplateVariables};
9use crate::tools::{KebabCaseHelper, LowercaseHelper, SnakeCaseHelper, UppercaseHelper};
10
11pub struct TemplateEngine {
13 handlebars: Handlebars<'static>,
15 variables: TemplateVariables,
17}
18
19impl TemplateEngine {
20 pub fn new(variables: TemplateVariables) -> Self {
22 let mut handlebars = Handlebars::new();
23
24 handlebars.set_strict_mode(true);
26
27 handlebars.register_helper("lowercase", Box::new(LowercaseHelper));
29 handlebars.register_helper("uppercase", Box::new(UppercaseHelper));
30 handlebars.register_helper("snake_case", Box::new(SnakeCaseHelper));
31 handlebars.register_helper("kebab_case", Box::new(KebabCaseHelper));
32
33 Self {
34 handlebars,
35 variables,
36 }
37 }
38
39 pub fn register_template(&mut self, name: &str, content: &str) -> Result<()> {
41 self.handlebars
42 .register_template_string(name, content)
43 .map_err(|e| TemplateError::RenderError {
44 name: name.to_string(),
45 source: e.into(),
46 })
47 }
48
49 pub fn render(&self, template_name: &str) -> Result<String> {
51 self.handlebars
52 .render(template_name, &self.variables)
53 .map_err(|e| TemplateError::RenderError {
54 name: template_name.to_string(),
55 source: e,
56 })
57 }
58
59 pub fn render_template(&self, template_content: &str) -> Result<String> {
61 self.handlebars
62 .render_template(template_content, &self.variables)
63 .map_err(|e| TemplateError::RenderError {
64 name: "string_template".to_string(),
65 source: e,
66 })
67 }
68
69 pub fn variables(&self) -> &TemplateVariables {
71 &self.variables
72 }
73
74 pub fn variables_mut(&mut self) -> &mut TemplateVariables {
76 &mut self.variables
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use crate::template::variables::TemplateVariables;
84 use pretty_assertions::assert_eq;
85
86 #[test]
87 fn test_render_template() {
88 let variables = TemplateVariables::default_test_variables();
89 let engine = TemplateEngine::new(variables);
90
91 let template =
92 "# {{name}}\n\n{{#if description}}{{description}}{{/if}}\n\nLicense: {{license}}";
93 let expected = "# test-project\n\nA test project\n\nLicense: MIT";
94
95 let result = engine.render_template(template).unwrap();
96 assert_eq!(result, expected);
97 }
98
99 #[test]
100 fn test_conditional_sections() {
101 let mut variables = TemplateVariables::default_test_variables();
102 variables.description = None;
103
104 let engine = TemplateEngine::new(variables);
105
106 let template = "# {{name}}\n\n{{#if description}}{{description}}{{else}}No description{{/if}}\n\nLicense: {{license}}";
107 let expected = "# test-project\n\nNo description\n\nLicense: MIT";
108
109 let result = engine.render_template(template).unwrap();
110 assert_eq!(result, expected);
111 }
112
113 #[test]
114 fn test_project_type_conditions() {
115 let variables = TemplateVariables::default_test_variables();
116 let engine = TemplateEngine::new(variables);
117
118 let template = "{{#if project.is_binary}}Binary{{else}}Library{{/if}}";
119 let expected = "Binary";
120
121 let result = engine.render_template(template).unwrap();
122 assert_eq!(result, expected);
123 }
124
125 #[test]
126 fn test_register_template_invalid_syntax() {
127 let variables = TemplateVariables::default_test_variables();
128 let mut engine = TemplateEngine::new(variables);
129 let result = engine.register_template("bad", "{{#if}");
131 assert!(result.is_err());
132 }
133
134 #[test]
135 fn test_render_unregistered_template() {
136 let variables = TemplateVariables::default_test_variables();
137 let engine = TemplateEngine::new(variables);
138 let result = engine.render("not_registered");
140 assert!(result.is_err());
141 }
142
143 #[test]
144 fn test_render_template_invalid_content() {
145 let variables = TemplateVariables::default_test_variables();
146 let engine = TemplateEngine::new(variables);
147 let result = engine.render_template("{{#if}");
149 assert!(result.is_err());
150 }
151
152 #[test]
153 fn test_variables_accessors() {
154 let variables = TemplateVariables::default_test_variables();
155 let mut engine = TemplateEngine::new(variables.clone());
156 assert_eq!(engine.variables().name, variables.name);
157 engine.variables_mut().name = "changed".to_string();
158 assert_eq!(engine.variables().name, "changed");
159 }
160}