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 match name {
224 "feature-spec" => Some(PromptTemplate::FeatureSpec),
225 "bug-fix" => Some(PromptTemplate::BugFix),
226 "refactor" => Some(PromptTemplate::Refactor),
227 "test" => Some(PromptTemplate::Test),
228 "docs" => Some(PromptTemplate::Docs),
229 "quick" => Some(PromptTemplate::Quick),
230 "performance-optimization" => Some(PromptTemplate::PerformanceOptimization),
231 "security-audit" => Some(PromptTemplate::SecurityAudit),
232 "api-integration" => Some(PromptTemplate::ApiIntegration),
233 "database-migration" => Some(PromptTemplate::DatabaseMigration),
234 "dependency-update" => Some(PromptTemplate::DependencyUpdate),
235 "cli-tool" => Some(PromptTemplate::CliTool),
236 "web-api" => Some(PromptTemplate::WebApi),
237 "data-pipeline" => Some(PromptTemplate::DataPipeline),
238 "ui-component" => Some(PromptTemplate::UiComponent),
239 "code-review" => Some(PromptTemplate::CodeReview),
240 "debug-triage" => Some(PromptTemplate::DebugTriage),
241 "release" => Some(PromptTemplate::Release),
242 "tech-debt" => Some(PromptTemplate::TechDebt),
243 "onboarding" => Some(PromptTemplate::Onboarding),
244 _ => None,
245 }
246}
247
248#[must_use]
252pub fn list_templates() -> Vec<(&'static str, &'static str)> {
253 vec![
254 (
255 PromptTemplate::FeatureSpec.name(),
256 PromptTemplate::FeatureSpec.description(),
257 ),
258 (
259 PromptTemplate::BugFix.name(),
260 PromptTemplate::BugFix.description(),
261 ),
262 (
263 PromptTemplate::Refactor.name(),
264 PromptTemplate::Refactor.description(),
265 ),
266 (
267 PromptTemplate::Test.name(),
268 PromptTemplate::Test.description(),
269 ),
270 (
271 PromptTemplate::Docs.name(),
272 PromptTemplate::Docs.description(),
273 ),
274 (
275 PromptTemplate::Quick.name(),
276 PromptTemplate::Quick.description(),
277 ),
278 (
279 PromptTemplate::PerformanceOptimization.name(),
280 PromptTemplate::PerformanceOptimization.description(),
281 ),
282 (
283 PromptTemplate::SecurityAudit.name(),
284 PromptTemplate::SecurityAudit.description(),
285 ),
286 (
287 PromptTemplate::ApiIntegration.name(),
288 PromptTemplate::ApiIntegration.description(),
289 ),
290 (
291 PromptTemplate::DatabaseMigration.name(),
292 PromptTemplate::DatabaseMigration.description(),
293 ),
294 (
295 PromptTemplate::DependencyUpdate.name(),
296 PromptTemplate::DependencyUpdate.description(),
297 ),
298 (
299 PromptTemplate::CliTool.name(),
300 PromptTemplate::CliTool.description(),
301 ),
302 (
303 PromptTemplate::WebApi.name(),
304 PromptTemplate::WebApi.description(),
305 ),
306 (
307 PromptTemplate::DataPipeline.name(),
308 PromptTemplate::DataPipeline.description(),
309 ),
310 (
311 PromptTemplate::UiComponent.name(),
312 PromptTemplate::UiComponent.description(),
313 ),
314 (
315 PromptTemplate::CodeReview.name(),
316 PromptTemplate::CodeReview.description(),
317 ),
318 (
319 PromptTemplate::DebugTriage.name(),
320 PromptTemplate::DebugTriage.description(),
321 ),
322 (
323 PromptTemplate::Release.name(),
324 PromptTemplate::Release.description(),
325 ),
326 (
327 PromptTemplate::TechDebt.name(),
328 PromptTemplate::TechDebt.description(),
329 ),
330 (
331 PromptTemplate::Onboarding.name(),
332 PromptTemplate::Onboarding.description(),
333 ),
334 ]
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340
341 #[test]
342 fn test_template_names() {
343 assert_eq!(PromptTemplate::FeatureSpec.name(), "feature-spec");
344 assert_eq!(PromptTemplate::BugFix.name(), "bug-fix");
345 assert_eq!(PromptTemplate::Refactor.name(), "refactor");
346 assert_eq!(PromptTemplate::Test.name(), "test");
347 assert_eq!(PromptTemplate::Docs.name(), "docs");
348 assert_eq!(PromptTemplate::Quick.name(), "quick");
349 assert_eq!(
350 PromptTemplate::PerformanceOptimization.name(),
351 "performance-optimization"
352 );
353 assert_eq!(PromptTemplate::SecurityAudit.name(), "security-audit");
354 assert_eq!(PromptTemplate::ApiIntegration.name(), "api-integration");
355 assert_eq!(
356 PromptTemplate::DatabaseMigration.name(),
357 "database-migration"
358 );
359 assert_eq!(PromptTemplate::DependencyUpdate.name(), "dependency-update");
360 assert_eq!(PromptTemplate::CliTool.name(), "cli-tool");
361 assert_eq!(PromptTemplate::WebApi.name(), "web-api");
362 assert_eq!(PromptTemplate::DataPipeline.name(), "data-pipeline");
363 assert_eq!(PromptTemplate::UiComponent.name(), "ui-component");
364 assert_eq!(PromptTemplate::CodeReview.name(), "code-review");
365 assert_eq!(PromptTemplate::DebugTriage.name(), "debug-triage");
366 assert_eq!(PromptTemplate::Release.name(), "release");
367 assert_eq!(PromptTemplate::TechDebt.name(), "tech-debt");
368 assert_eq!(PromptTemplate::Onboarding.name(), "onboarding");
369 }
370
371 #[test]
372 fn test_template_descriptions() {
373 assert!(!PromptTemplate::FeatureSpec.description().is_empty());
374 assert!(!PromptTemplate::BugFix.description().is_empty());
375 assert!(!PromptTemplate::Refactor.description().is_empty());
376 assert!(!PromptTemplate::Test.description().is_empty());
377 assert!(!PromptTemplate::Docs.description().is_empty());
378 assert!(!PromptTemplate::Quick.description().is_empty());
379 assert!(!PromptTemplate::PerformanceOptimization
380 .description()
381 .is_empty());
382 assert!(!PromptTemplate::SecurityAudit.description().is_empty());
383 assert!(!PromptTemplate::ApiIntegration.description().is_empty());
384 assert!(!PromptTemplate::DatabaseMigration.description().is_empty());
385 assert!(!PromptTemplate::DependencyUpdate.description().is_empty());
386 assert!(!PromptTemplate::CliTool.description().is_empty());
387 assert!(!PromptTemplate::WebApi.description().is_empty());
388 assert!(!PromptTemplate::DataPipeline.description().is_empty());
389 assert!(!PromptTemplate::UiComponent.description().is_empty());
390 assert!(!PromptTemplate::CodeReview.description().is_empty());
391 assert!(!PromptTemplate::DebugTriage.description().is_empty());
392 assert!(!PromptTemplate::Release.description().is_empty());
393 assert!(!PromptTemplate::TechDebt.description().is_empty());
394 assert!(!PromptTemplate::Onboarding.description().is_empty());
395 }
396
397 #[test]
398 fn test_get_template() {
399 assert_eq!(
400 get_template("feature-spec"),
401 Some(PromptTemplate::FeatureSpec)
402 );
403 assert_eq!(get_template("bug-fix"), Some(PromptTemplate::BugFix));
404 assert_eq!(
405 get_template("performance-optimization"),
406 Some(PromptTemplate::PerformanceOptimization)
407 );
408 assert_eq!(
409 get_template("security-audit"),
410 Some(PromptTemplate::SecurityAudit)
411 );
412 assert_eq!(
413 get_template("api-integration"),
414 Some(PromptTemplate::ApiIntegration)
415 );
416 assert_eq!(
417 get_template("database-migration"),
418 Some(PromptTemplate::DatabaseMigration)
419 );
420 assert_eq!(
421 get_template("dependency-update"),
422 Some(PromptTemplate::DependencyUpdate)
423 );
424 assert_eq!(get_template("cli-tool"), Some(PromptTemplate::CliTool));
425 assert_eq!(get_template("web-api"), Some(PromptTemplate::WebApi));
426 assert_eq!(
427 get_template("data-pipeline"),
428 Some(PromptTemplate::DataPipeline)
429 );
430 assert_eq!(
431 get_template("ui-component"),
432 Some(PromptTemplate::UiComponent)
433 );
434 assert_eq!(
435 get_template("code-review"),
436 Some(PromptTemplate::CodeReview)
437 );
438 assert_eq!(
439 get_template("debug-triage"),
440 Some(PromptTemplate::DebugTriage)
441 );
442 assert_eq!(get_template("release"), Some(PromptTemplate::Release));
443 assert_eq!(get_template("tech-debt"), Some(PromptTemplate::TechDebt));
444 assert_eq!(get_template("onboarding"), Some(PromptTemplate::Onboarding));
445 assert_eq!(get_template("nonexistent"), None);
446 }
447
448 #[test]
449 fn test_list_templates() {
450 let templates = list_templates();
451 assert_eq!(templates.len(), 20);
452 assert!(templates.iter().any(|(name, _)| name == &"feature-spec"));
453 assert!(templates.iter().any(|(name, _)| name == &"bug-fix"));
454 assert!(templates
455 .iter()
456 .any(|(name, _)| name == &"performance-optimization"));
457 assert!(templates.iter().any(|(name, _)| name == &"security-audit"));
458 assert!(templates.iter().any(|(name, _)| name == &"api-integration"));
459 assert!(templates
460 .iter()
461 .any(|(name, _)| name == &"database-migration"));
462 assert!(templates
463 .iter()
464 .any(|(name, _)| name == &"dependency-update"));
465 assert!(templates.iter().any(|(name, _)| name == &"cli-tool"));
466 assert!(templates.iter().any(|(name, _)| name == &"web-api"));
467 assert!(templates.iter().any(|(name, _)| name == &"data-pipeline"));
468 assert!(templates.iter().any(|(name, _)| name == &"ui-component"));
469 assert!(templates.iter().any(|(name, _)| name == &"code-review"));
470 assert!(templates.iter().any(|(name, _)| name == &"debug-triage"));
471 assert!(templates.iter().any(|(name, _)| name == &"release"));
472 assert!(templates.iter().any(|(name, _)| name == &"tech-debt"));
473 assert!(templates.iter().any(|(name, _)| name == &"onboarding"));
474 }
475
476 #[test]
477 fn test_template_content_has_goal() {
478 ALL_TEMPLATES.iter().for_each(|template| {
479 let content = template.content();
480 assert!(
481 content.contains("## Goal"),
482 "Template {} missing Goal section",
483 template.name()
484 );
485 });
486 }
487
488 #[test]
489 fn test_template_content_has_acceptance() {
490 ALL_TEMPLATES.iter().for_each(|template| {
491 let content = template.content();
492 assert!(
493 content.contains("## Acceptance") || content.contains("## Acceptance Checks"),
494 "Template {} missing Acceptance section",
495 template.name()
496 );
497 });
498 }
499}