1use super::{Template, TemplateCategory};
4use crate::{Result, format::RuleCategory, parser::UnifiedRule};
5
6#[derive(Debug, Clone)]
8pub struct TaskTemplate {
9 name: String,
10 description: String,
11 standards: Vec<(RuleCategory, String)>,
12 tags: Vec<String>,
13}
14
15impl TaskTemplate {
16 pub fn implement_feature() -> Self {
18 Self {
19 name: "implement-feature".to_string(),
20 description: "Guidance for implementing a new feature".to_string(),
21 standards: vec![
22 (
23 RuleCategory::Architecture,
24 "Consider how this feature fits into the overall architecture".to_string(),
25 ),
26 (
27 RuleCategory::Style,
28 "Follow existing code patterns in the codebase".to_string(),
29 ),
30 (
31 RuleCategory::Testing,
32 "Write tests alongside the implementation".to_string(),
33 ),
34 (
35 RuleCategory::Documentation,
36 "Update relevant documentation".to_string(),
37 ),
38 (
39 RuleCategory::Other,
40 "Consider backward compatibility".to_string(),
41 ),
42 ],
43 tags: vec![
44 "feature".to_string(),
45 "implement".to_string(),
46 "development".to_string(),
47 ],
48 }
49 }
50
51 pub fn write_tests() -> Self {
53 Self {
54 name: "write-tests".to_string(),
55 description: "Guidance for writing comprehensive tests".to_string(),
56 standards: vec![
57 (
58 RuleCategory::Testing,
59 "Test both happy path and error cases".to_string(),
60 ),
61 (
62 RuleCategory::Testing,
63 "Use descriptive test names".to_string(),
64 ),
65 (
66 RuleCategory::Testing,
67 "Keep tests isolated and independent".to_string(),
68 ),
69 (
70 RuleCategory::Testing,
71 "Mock external dependencies".to_string(),
72 ),
73 (
74 RuleCategory::Testing,
75 "Test edge cases and boundary conditions".to_string(),
76 ),
77 (
78 RuleCategory::Testing,
79 "Aim for meaningful coverage, not just high numbers".to_string(),
80 ),
81 ],
82 tags: vec![
83 "testing".to_string(),
84 "tests".to_string(),
85 "quality".to_string(),
86 ],
87 }
88 }
89
90 pub fn fix_bug() -> Self {
92 Self {
93 name: "fix-bug".to_string(),
94 description: "Guidance for fixing bugs systematically".to_string(),
95 standards: vec![
96 (RuleCategory::Other, "First reproduce the bug".to_string()),
97 (
98 RuleCategory::Other,
99 "Understand the root cause before fixing".to_string(),
100 ),
101 (
102 RuleCategory::Testing,
103 "Write a failing test that reproduces the bug".to_string(),
104 ),
105 (
106 RuleCategory::Other,
107 "Check for similar issues elsewhere".to_string(),
108 ),
109 (
110 RuleCategory::Other,
111 "Consider if this indicates a design issue".to_string(),
112 ),
113 ],
114 tags: vec![
115 "bug".to_string(),
116 "fix".to_string(),
117 "debugging".to_string(),
118 ],
119 }
120 }
121
122 pub fn optimize() -> Self {
124 Self {
125 name: "optimize".to_string(),
126 description: "Guidance for performance optimization".to_string(),
127 standards: vec![
128 (
129 RuleCategory::Performance,
130 "Measure before optimizing".to_string(),
131 ),
132 (
133 RuleCategory::Performance,
134 "Identify the bottleneck first".to_string(),
135 ),
136 (
137 RuleCategory::Performance,
138 "Consider algorithmic improvements before micro-optimizations".to_string(),
139 ),
140 (
141 RuleCategory::Performance,
142 "Document the optimization and its impact".to_string(),
143 ),
144 (
145 RuleCategory::Testing,
146 "Ensure functionality is preserved".to_string(),
147 ),
148 (
149 RuleCategory::Performance,
150 "Measure after to confirm improvement".to_string(),
151 ),
152 ],
153 tags: vec![
154 "performance".to_string(),
155 "optimization".to_string(),
156 "speed".to_string(),
157 ],
158 }
159 }
160
161 pub fn document() -> Self {
163 Self {
164 name: "document".to_string(),
165 description: "Guidance for writing documentation".to_string(),
166 standards: vec![
167 (
168 RuleCategory::Documentation,
169 "Write for the reader, not the writer".to_string(),
170 ),
171 (
172 RuleCategory::Documentation,
173 "Include practical examples".to_string(),
174 ),
175 (
176 RuleCategory::Documentation,
177 "Keep it concise but complete".to_string(),
178 ),
179 (
180 RuleCategory::Documentation,
181 "Use proper formatting and structure".to_string(),
182 ),
183 (
184 RuleCategory::Documentation,
185 "Explain the 'why', not just the 'what'".to_string(),
186 ),
187 (
188 RuleCategory::Documentation,
189 "Consider different audience skill levels".to_string(),
190 ),
191 ],
192 tags: vec![
193 "documentation".to_string(),
194 "docs".to_string(),
195 "writing".to_string(),
196 ],
197 }
198 }
199}
200
201impl Template for TaskTemplate {
202 fn name(&self) -> &str {
203 &self.name
204 }
205
206 fn description(&self) -> &str {
207 &self.description
208 }
209
210 fn category(&self) -> TemplateCategory {
211 TemplateCategory::Task
212 }
213
214 fn expand(&self) -> Result<Vec<UnifiedRule>> {
215 Ok(self
216 .standards
217 .iter()
218 .enumerate()
219 .map(|(i, (category, description))| UnifiedRule::Standard {
220 category: *category,
221 priority: i as u8,
222 description: description.clone(),
223 pattern: None,
224 })
225 .collect())
226 }
227
228 fn tags(&self) -> Vec<&str> {
229 self.tags.iter().map(|s| s.as_str()).collect()
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn test_implement_feature() {
239 let template = TaskTemplate::implement_feature();
240 assert_eq!(template.name(), "implement-feature");
241 assert_eq!(template.category(), TemplateCategory::Task);
242
243 let rules = template.expand().unwrap();
244 assert!(!rules.is_empty());
245 }
246}