1use std::fmt;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum PromptTemplate {
16 FeatureSpec,
18 BugFix,
20 Refactor,
22 Test,
24 Docs,
26 Quick,
28 PerformanceOptimization,
30 SecurityAudit,
32 ApiIntegration,
34 DatabaseMigration,
36 DependencyUpdate,
38 CliTool,
40 WebApi,
42 DataPipeline,
44 UiComponent,
46 CodeReview,
48 DebugTriage,
50 Release,
52 TechDebt,
54 Onboarding,
56}
57
58impl PromptTemplate {
59 #[must_use]
61 pub const fn name(self) -> &'static str {
62 match self {
63 Self::FeatureSpec => "feature-spec",
64 Self::BugFix => "bug-fix",
65 Self::Refactor => "refactor",
66 Self::Test => "test",
67 Self::Docs => "docs",
68 Self::Quick => "quick",
69 Self::PerformanceOptimization => "performance-optimization",
70 Self::SecurityAudit => "security-audit",
71 Self::ApiIntegration => "api-integration",
72 Self::DatabaseMigration => "database-migration",
73 Self::DependencyUpdate => "dependency-update",
74 Self::CliTool => "cli-tool",
75 Self::WebApi => "web-api",
76 Self::DataPipeline => "data-pipeline",
77 Self::UiComponent => "ui-component",
78 Self::CodeReview => "code-review",
79 Self::DebugTriage => "debug-triage",
80 Self::Release => "release",
81 Self::TechDebt => "tech-debt",
82 Self::Onboarding => "onboarding",
83 }
84 }
85
86 #[must_use]
88 pub const fn description(self) -> &'static str {
89 match self {
90 Self::FeatureSpec => "Comprehensive product specification with questions to consider and code quality standards",
91 Self::BugFix => "Bug fix template with investigation guidance and testing requirements",
92 Self::Refactor => "Code refactoring template with behavior preservation emphasis",
93 Self::Test => "Test writing template with edge case considerations",
94 Self::Docs => "Documentation update template with completeness checklist",
95 Self::Quick => "Quick/small change template (minimal)",
96 Self::PerformanceOptimization => "Performance optimization template with benchmarking and profiling guidance",
97 Self::SecurityAudit => "Security audit template covering OWASP Top 10 and vulnerability remediation",
98 Self::ApiIntegration => "API integration template with error handling, retry logic, and resilience patterns",
99 Self::DatabaseMigration => "Database migration template with zero-downtime strategies and rollback plans",
100 Self::DependencyUpdate => "Dependency update template with migration guides and breaking change handling",
101 Self::CliTool => "CLI tool development template with argument parsing, completion, and error handling",
102 Self::WebApi => "Web API development template with REST design, error handling, and security considerations",
103 Self::DataPipeline => "Data pipeline template with ETL processing, reliability, and monitoring guidance",
104 Self::UiComponent => "UI component template with accessibility, responsive design, and user experience",
105 Self::CodeReview => "Code review template for structured pull request feedback",
106 Self::DebugTriage => "Debug triage template for systematic issue investigation and diagnosis",
107 Self::Release => "Release preparation template with versioning, changelog, and deployment checklist",
108 Self::TechDebt => "Technical debt refactoring template with prioritization and planning guidance",
109 Self::Onboarding => "Onboarding template for learning new codebases efficiently",
110 }
111 }
112
113 #[must_use]
115 pub const fn content(self) -> &'static str {
116 match self {
117 Self::FeatureSpec => {
118 include_str!("../../templates/prompts/feature-spec.md")
119 }
120 Self::BugFix => {
121 include_str!("../../templates/prompts/bug-fix.md")
122 }
123 Self::Refactor => {
124 include_str!("../../templates/prompts/refactor.md")
125 }
126 Self::Test => {
127 include_str!("../../templates/prompts/test.md")
128 }
129 Self::Docs => {
130 include_str!("../../templates/prompts/docs.md")
131 }
132 Self::Quick => {
133 include_str!("../../templates/prompts/quick.md")
134 }
135 Self::PerformanceOptimization => {
136 include_str!("../../templates/prompts/performance-optimization.md")
137 }
138 Self::SecurityAudit => {
139 include_str!("../../templates/prompts/security-audit.md")
140 }
141 Self::ApiIntegration => {
142 include_str!("../../templates/prompts/api-integration.md")
143 }
144 Self::DatabaseMigration => {
145 include_str!("../../templates/prompts/database-migration.md")
146 }
147 Self::DependencyUpdate => {
148 include_str!("../../templates/prompts/dependency-update.md")
149 }
150 Self::CliTool => {
151 include_str!("../../templates/prompts/cli-tool.md")
152 }
153 Self::WebApi => {
154 include_str!("../../templates/prompts/web-api.md")
155 }
156 Self::DataPipeline => {
157 include_str!("../../templates/prompts/data-pipeline.md")
158 }
159 Self::UiComponent => {
160 include_str!("../../templates/prompts/ui-component.md")
161 }
162 Self::CodeReview => {
163 include_str!("../../templates/prompts/code-review.md")
164 }
165 Self::DebugTriage => {
166 include_str!("../../templates/prompts/debug-triage.md")
167 }
168 Self::Release => {
169 include_str!("../../templates/prompts/release.md")
170 }
171 Self::TechDebt => {
172 include_str!("../../templates/prompts/tech-debt.md")
173 }
174 Self::Onboarding => {
175 include_str!("../../templates/prompts/onboarding.md")
176 }
177 }
178 }
179}
180
181impl fmt::Display for PromptTemplate {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 write!(f, "{}", self.name())
184 }
185}
186
187pub const ALL_TEMPLATES: [PromptTemplate; 20] = [
189 PromptTemplate::FeatureSpec,
190 PromptTemplate::BugFix,
191 PromptTemplate::Refactor,
192 PromptTemplate::Test,
193 PromptTemplate::Docs,
194 PromptTemplate::Quick,
195 PromptTemplate::PerformanceOptimization,
196 PromptTemplate::SecurityAudit,
197 PromptTemplate::ApiIntegration,
198 PromptTemplate::DatabaseMigration,
199 PromptTemplate::DependencyUpdate,
200 PromptTemplate::CliTool,
201 PromptTemplate::WebApi,
202 PromptTemplate::DataPipeline,
203 PromptTemplate::UiComponent,
204 PromptTemplate::CodeReview,
205 PromptTemplate::DebugTriage,
206 PromptTemplate::Release,
207 PromptTemplate::TechDebt,
208 PromptTemplate::Onboarding,
209];
210
211#[must_use]
222pub fn get_template(name: &str) -> Option<PromptTemplate> {
223 ALL_TEMPLATES.iter().find(|t| t.name() == name).copied()
224}
225
226#[must_use]
230pub fn list_templates() -> Vec<(&'static str, &'static str)> {
231 ALL_TEMPLATES
232 .iter()
233 .map(|t| (t.name(), t.description()))
234 .collect()
235}
236
237#[cfg(test)]
238mod tests {
239 use super::*;
240
241 #[test]
242 fn test_template_names() {
243 assert_eq!(PromptTemplate::FeatureSpec.name(), "feature-spec");
244 assert_eq!(PromptTemplate::BugFix.name(), "bug-fix");
245 assert_eq!(PromptTemplate::Refactor.name(), "refactor");
246 assert_eq!(PromptTemplate::Test.name(), "test");
247 assert_eq!(PromptTemplate::Docs.name(), "docs");
248 assert_eq!(PromptTemplate::Quick.name(), "quick");
249 assert_eq!(
250 PromptTemplate::PerformanceOptimization.name(),
251 "performance-optimization"
252 );
253 assert_eq!(PromptTemplate::SecurityAudit.name(), "security-audit");
254 assert_eq!(PromptTemplate::ApiIntegration.name(), "api-integration");
255 assert_eq!(
256 PromptTemplate::DatabaseMigration.name(),
257 "database-migration"
258 );
259 assert_eq!(PromptTemplate::DependencyUpdate.name(), "dependency-update");
260 assert_eq!(PromptTemplate::CliTool.name(), "cli-tool");
261 assert_eq!(PromptTemplate::WebApi.name(), "web-api");
262 assert_eq!(PromptTemplate::DataPipeline.name(), "data-pipeline");
263 assert_eq!(PromptTemplate::UiComponent.name(), "ui-component");
264 assert_eq!(PromptTemplate::CodeReview.name(), "code-review");
265 assert_eq!(PromptTemplate::DebugTriage.name(), "debug-triage");
266 assert_eq!(PromptTemplate::Release.name(), "release");
267 assert_eq!(PromptTemplate::TechDebt.name(), "tech-debt");
268 assert_eq!(PromptTemplate::Onboarding.name(), "onboarding");
269 }
270
271 #[test]
272 fn test_template_descriptions() {
273 assert!(!PromptTemplate::FeatureSpec.description().is_empty());
274 assert!(!PromptTemplate::BugFix.description().is_empty());
275 assert!(!PromptTemplate::Refactor.description().is_empty());
276 assert!(!PromptTemplate::Test.description().is_empty());
277 assert!(!PromptTemplate::Docs.description().is_empty());
278 assert!(!PromptTemplate::Quick.description().is_empty());
279 assert!(!PromptTemplate::PerformanceOptimization
280 .description()
281 .is_empty());
282 assert!(!PromptTemplate::SecurityAudit.description().is_empty());
283 assert!(!PromptTemplate::ApiIntegration.description().is_empty());
284 assert!(!PromptTemplate::DatabaseMigration.description().is_empty());
285 assert!(!PromptTemplate::DependencyUpdate.description().is_empty());
286 assert!(!PromptTemplate::CliTool.description().is_empty());
287 assert!(!PromptTemplate::WebApi.description().is_empty());
288 assert!(!PromptTemplate::DataPipeline.description().is_empty());
289 assert!(!PromptTemplate::UiComponent.description().is_empty());
290 assert!(!PromptTemplate::CodeReview.description().is_empty());
291 assert!(!PromptTemplate::DebugTriage.description().is_empty());
292 assert!(!PromptTemplate::Release.description().is_empty());
293 assert!(!PromptTemplate::TechDebt.description().is_empty());
294 assert!(!PromptTemplate::Onboarding.description().is_empty());
295 }
296
297 #[test]
298 fn test_get_template() {
299 assert_eq!(
300 get_template("feature-spec"),
301 Some(PromptTemplate::FeatureSpec)
302 );
303 assert_eq!(get_template("bug-fix"), Some(PromptTemplate::BugFix));
304 assert_eq!(
305 get_template("performance-optimization"),
306 Some(PromptTemplate::PerformanceOptimization)
307 );
308 assert_eq!(
309 get_template("security-audit"),
310 Some(PromptTemplate::SecurityAudit)
311 );
312 assert_eq!(
313 get_template("api-integration"),
314 Some(PromptTemplate::ApiIntegration)
315 );
316 assert_eq!(
317 get_template("database-migration"),
318 Some(PromptTemplate::DatabaseMigration)
319 );
320 assert_eq!(
321 get_template("dependency-update"),
322 Some(PromptTemplate::DependencyUpdate)
323 );
324 assert_eq!(get_template("cli-tool"), Some(PromptTemplate::CliTool));
325 assert_eq!(get_template("web-api"), Some(PromptTemplate::WebApi));
326 assert_eq!(
327 get_template("data-pipeline"),
328 Some(PromptTemplate::DataPipeline)
329 );
330 assert_eq!(
331 get_template("ui-component"),
332 Some(PromptTemplate::UiComponent)
333 );
334 assert_eq!(
335 get_template("code-review"),
336 Some(PromptTemplate::CodeReview)
337 );
338 assert_eq!(
339 get_template("debug-triage"),
340 Some(PromptTemplate::DebugTriage)
341 );
342 assert_eq!(get_template("release"), Some(PromptTemplate::Release));
343 assert_eq!(get_template("tech-debt"), Some(PromptTemplate::TechDebt));
344 assert_eq!(get_template("onboarding"), Some(PromptTemplate::Onboarding));
345 assert_eq!(get_template("nonexistent"), None);
346 }
347
348 #[test]
349 fn test_list_templates() {
350 let templates = list_templates();
351 assert_eq!(templates.len(), 20);
352 assert!(templates.iter().any(|(name, _)| name == &"feature-spec"));
353 assert!(templates.iter().any(|(name, _)| name == &"bug-fix"));
354 assert!(templates
355 .iter()
356 .any(|(name, _)| name == &"performance-optimization"));
357 assert!(templates.iter().any(|(name, _)| name == &"security-audit"));
358 assert!(templates.iter().any(|(name, _)| name == &"api-integration"));
359 assert!(templates
360 .iter()
361 .any(|(name, _)| name == &"database-migration"));
362 assert!(templates
363 .iter()
364 .any(|(name, _)| name == &"dependency-update"));
365 assert!(templates.iter().any(|(name, _)| name == &"cli-tool"));
366 assert!(templates.iter().any(|(name, _)| name == &"web-api"));
367 assert!(templates.iter().any(|(name, _)| name == &"data-pipeline"));
368 assert!(templates.iter().any(|(name, _)| name == &"ui-component"));
369 assert!(templates.iter().any(|(name, _)| name == &"code-review"));
370 assert!(templates.iter().any(|(name, _)| name == &"debug-triage"));
371 assert!(templates.iter().any(|(name, _)| name == &"release"));
372 assert!(templates.iter().any(|(name, _)| name == &"tech-debt"));
373 assert!(templates.iter().any(|(name, _)| name == &"onboarding"));
374 }
375
376 #[test]
377 fn test_template_content_has_goal() {
378 for template in ALL_TEMPLATES {
379 let content = template.content();
380 assert!(
381 content.contains("## Goal"),
382 "Template {} missing Goal section",
383 template.name()
384 );
385 }
386 }
387
388 #[test]
389 fn test_template_content_has_acceptance() {
390 for template in ALL_TEMPLATES {
391 let content = template.content();
392 assert!(
393 content.contains("## Acceptance") || content.contains("## Acceptance Checks"),
394 "Template {} missing Acceptance section",
395 template.name()
396 );
397 }
398 }
399}