1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
//! Template system for customizable prompt generation.
//!
//! This module provides the core template rendering functionality using the Handlebars templating engine.
//! It supports dynamic content generation with built-in variables for code content, file metadata, and
//! project structure. The system includes utilities for template validation, variable extraction, and
//! output management.
//!
//! ## Available Template Variables
//!
//! Templates can use the following built-in variables:
//! - `absolute_code_path` - Absolute path to the code directory
//! - `source_tree` - Directory structure visualization
//! - `files` - Collection of processed files with metadata
//! - `path` - Relative file paths
//! - `code` - File contents
//! - `extension` - File extension
//! - `no_codeblock` - Flag to control code block formatting
//! - `git_diff` - Git diff content
//! - `git_diff_branch` - Git diff against specific branch
//! - `git_log_branch` - Git log for specific branch
//!
//! ## Usage Example
//!
//! ```rust
//! use code2prompt_core::template::{handlebars_setup, render_template};
//! use serde_json::json;
//!
//! let template = "# Code Analysis\n{{#each files}}\n## {{path}}\n```{{extension}}\n{{code}}\n```\n{{/each}}";
//! let handlebars = handlebars_setup(template, "analysis")?;
//! let data = json!({"files": [{"path": "main.rs", "extension": "rust", "code": "fn main() {}"}]});
//! let output = render_template(&handlebars, "analysis", &data)?;
//! # Ok::<(), anyhow::Error>(())
//! ```
use ;
use ;
use Regex;
use ;
use Write;
/// Creates and configures a Handlebars template engine instance.
///
/// Sets up a Handlebars instance with HTML escaping disabled (using `no_escape`)
/// and registers the provided template string under the specified name. This is
/// the primary setup function for template rendering in the code2prompt system.
///
/// # Arguments
///
/// * `template_str` - The Handlebars template string containing template syntax
/// * `template_name` - Unique identifier for the template within the Handlebars registry
///
/// # Returns
///
/// * `Result<Handlebars<'static>>` - Configured Handlebars instance ready for rendering
///
/// # Errors
///
/// Returns an error if the template string contains invalid Handlebars syntax
/// or if template registration fails.
///
/// # Examples
///
/// ```rust
/// use code2prompt_core::template::handlebars_setup;
///
/// let template = "Hello {{name}}!";
/// let handlebars = handlebars_setup(template, "greeting")?;
/// # Ok::<(), anyhow::Error>(())
/// ```
/// Identifies unrecognized template variables that may require user definition.
///
/// Scans a Handlebars template string and extracts variable names that are not part
/// of the built-in variable set. This is useful for template validation and helping
/// users identify custom variables they need to provide data for.
///
/// The function recognizes these built-in variables and excludes them from the result:
/// - `absolute_code_path`, `source_tree`, `files`, `path`, `code`, `extension`
/// - `no_codeblock`, `git_diff`, `git_diff_branch`, `git_log_branch`
///
/// # Arguments
///
/// * `template` - The Handlebars template string to analyze
///
/// # Returns
///
/// * `Vec<String>` - Collection of undefined variable names found in the template
///
/// # Examples
///
/// ```rust
/// use code2prompt_core::template::extract_undefined_variables;
///
/// let template = "{{code}} and {{custom_var}} with {{another_custom}}";
/// let undefined = extract_undefined_variables(template);
/// assert_eq!(undefined, vec!["custom_var", "another_custom"]);
/// ```
/// Renders a registered template with the provided context data.
///
/// Takes a configured Handlebars instance and renders the specified template using
/// the provided data context. The output is automatically trimmed of leading and
/// trailing whitespace for cleaner results.
///
/// # Arguments
///
/// * `handlebars` - The configured Handlebars instance containing registered templates
/// * `template_name` - Name of the template to render (must be previously registered)
/// * `data` - Serializable data object providing values for template variables
///
/// # Returns
///
/// * `Result<String>` - The rendered template content as a trimmed string
///
/// # Errors
///
/// Returns an error if:
/// - The template name is not found in the registry
/// - Template rendering fails due to missing variables or syntax errors
/// - Data serialization fails
///
/// # Examples
///
/// ```rust
/// use code2prompt_core::template::{handlebars_setup, render_template};
/// use serde_json::json;
///
/// let handlebars = handlebars_setup("Hello {{name}}!", "greeting")?;
/// let data = json!({"name": "World"});
/// let output = render_template(&handlebars, "greeting", &data)?;
/// assert_eq!(output, "Hello World!");
/// # Ok::<(), anyhow::Error>(())
/// ```
/// Writes rendered template content to a file with buffered I/O.
///
/// Creates or overwrites a file at the specified path and writes the rendered
/// template content using a buffered writer for efficient I/O operations.
/// The file will be created if it doesn't exist, including any necessary parent directories.
///
/// # Arguments
///
/// * `output_path` - File system path where the content should be written
/// * `rendered` - The rendered template content to write to the file
///
/// # Returns
///
/// * `Result<()>` - Success indication or I/O error
///
/// # Errors
///
/// Returns an error if:
/// - The output path cannot be created or accessed
/// - File creation fails due to permissions or disk space
/// - Write operation fails
///
/// # Examples
///
/// ```rust,no_run
/// use code2prompt_core::template::write_to_file;
///
/// let content = "# Generated Report\n\nThis is the analysis output.";
/// write_to_file("output/report.md", content)?;
/// # Ok::<(), anyhow::Error>(())
/// ```
/// Supported output formats for template rendering.
///
/// Defines the available output formats that templates can target, each optimized
/// for different use cases and consumption by various tools or systems.
///
/// The enum supports serde serialization/deserialization with lowercase string
/// representation for configuration files and JSON APIs.