devflow-kit 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +23 -6
  3. package/dist/plugins.js +67 -3
  4. package/package.json +2 -1
  5. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  6. package/plugins/devflow-ambient/.claude-plugin/plugin.json +1 -1
  7. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +1 -1
  8. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +4 -0
  9. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  10. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  11. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  12. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  13. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  14. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +2 -6
  15. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  16. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  17. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  19. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  20. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  21. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  22. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  23. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  24. package/plugins/devflow-implement/agents/coder.md +11 -6
  25. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  26. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  27. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  28. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  29. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  30. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  31. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  32. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  33. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  34. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  35. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  36. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  37. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  38. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  39. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  40. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  41. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  42. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  43. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  44. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  45. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  46. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  47. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  48. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  49. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  50. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  51. package/shared/agents/coder.md +11 -6
  52. package/shared/agents/reviewer.md +8 -0
  53. package/shared/skills/ambient-router/SKILL.md +1 -1
  54. package/shared/skills/ambient-router/references/skill-catalog.md +4 -0
  55. package/shared/skills/go/SKILL.md +187 -0
  56. package/shared/skills/go/references/concurrency.md +312 -0
  57. package/shared/skills/go/references/detection.md +129 -0
  58. package/shared/skills/go/references/patterns.md +232 -0
  59. package/shared/skills/go/references/violations.md +205 -0
  60. package/shared/skills/java/SKILL.md +183 -0
  61. package/shared/skills/java/references/detection.md +120 -0
  62. package/shared/skills/java/references/modern-java.md +270 -0
  63. package/shared/skills/java/references/patterns.md +235 -0
  64. package/shared/skills/java/references/violations.md +213 -0
  65. package/shared/skills/python/SKILL.md +188 -0
  66. package/shared/skills/python/references/async.md +220 -0
  67. package/shared/skills/python/references/detection.md +128 -0
  68. package/shared/skills/python/references/patterns.md +226 -0
  69. package/shared/skills/python/references/violations.md +204 -0
  70. package/shared/skills/react/SKILL.md +1 -1
  71. package/shared/skills/react/references/patterns.md +3 -3
  72. package/shared/skills/rust/SKILL.md +193 -0
  73. package/shared/skills/rust/references/detection.md +131 -0
  74. package/shared/skills/rust/references/ownership.md +242 -0
  75. package/shared/skills/rust/references/patterns.md +210 -0
  76. package/shared/skills/rust/references/violations.md +191 -0
  77. package/shared/skills/typescript/references/patterns.md +3 -3
  78. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  79. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  80. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  81. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  82. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  83. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  84. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  85. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  86. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  87. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  88. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  89. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  90. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  91. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  92. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  93. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  94. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  95. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  96. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  97. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  98. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  99. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  100. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  101. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  102. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  103. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  104. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  105. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  106. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  107. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,131 @@
1
+ # Rust Detection Patterns
2
+
3
+ Grep and regex patterns for finding common Rust issues. Use with `Grep` tool.
4
+
5
+ ## Unwrap and Expect
6
+
7
+ ```bash
8
+ # Find .unwrap() calls (exclude tests)
9
+ grep -rn '\.unwrap()' --include='*.rs' --exclude-dir=tests --exclude='*_test.rs'
10
+
11
+ # Find .expect() without descriptive message
12
+ grep -rn '\.expect("")' --include='*.rs'
13
+
14
+ # Find unwrap_or_default hiding errors
15
+ grep -rn '\.unwrap_or_default()' --include='*.rs'
16
+ ```
17
+
18
+ **Pattern**: `\.unwrap\(\)` — matches any `.unwrap()` call
19
+ **Pattern**: `\.expect\("` — matches `.expect("` to review message quality
20
+
21
+ ---
22
+
23
+ ## Clone Abuse
24
+
25
+ ```bash
26
+ # Find .clone() calls — review each for necessity
27
+ grep -rn '\.clone()' --include='*.rs'
28
+
29
+ # Find clone in loop bodies (likely hot-path waste)
30
+ grep -rn -A2 'for.*in' --include='*.rs' | grep '\.clone()'
31
+
32
+ # Find to_string() where &str would work
33
+ grep -rn '\.to_string()' --include='*.rs'
34
+ ```
35
+
36
+ **Pattern**: `\.clone\(\)` — all clone calls for manual review
37
+ **Pattern**: `\.to_owned\(\)` — ownership transfer that may be unnecessary
38
+
39
+ ---
40
+
41
+ ## Unsafe Blocks
42
+
43
+ ```bash
44
+ # Find all unsafe blocks
45
+ grep -rn 'unsafe\s*{' --include='*.rs'
46
+
47
+ # Find unsafe without SAFETY comment
48
+ grep -rn -B2 'unsafe\s*{' --include='*.rs' | grep -v 'SAFETY'
49
+
50
+ # Find unsafe functions
51
+ grep -rn 'unsafe fn' --include='*.rs'
52
+ ```
53
+
54
+ **Pattern**: `unsafe\s*\{` — unsafe blocks
55
+ **Pattern**: `unsafe fn` — unsafe function declarations
56
+
57
+ ---
58
+
59
+ ## Incomplete Code
60
+
61
+ ```bash
62
+ # Find todo! and unimplemented! macros
63
+ grep -rn 'todo!\|unimplemented!' --include='*.rs'
64
+
65
+ # Find unreachable! that may hide bugs
66
+ grep -rn 'unreachable!' --include='*.rs'
67
+
68
+ # Find panic! in non-test code
69
+ grep -rn 'panic!' --include='*.rs' --exclude-dir=tests --exclude='*_test.rs'
70
+ ```
71
+
72
+ **Pattern**: `todo!\(\)` — placeholder code
73
+ **Pattern**: `unimplemented!\(\)` — unfinished implementations
74
+ **Pattern**: `panic!\(` — explicit panics outside tests
75
+
76
+ ---
77
+
78
+ ## Error Handling Issues
79
+
80
+ ```bash
81
+ # Find ignored Results (let _ = expr that returns Result)
82
+ grep -rn 'let _ =' --include='*.rs'
83
+
84
+ # Find empty match arms that may swallow errors
85
+ grep -rn '=> {}' --include='*.rs'
86
+
87
+ # Find catch-all match arms hiding missing cases
88
+ grep -rn '_ =>' --include='*.rs'
89
+ ```
90
+
91
+ **Pattern**: `let _ =` — potentially ignored Result or important value
92
+ **Pattern**: `=> \{\}` — empty match arm (may swallow error)
93
+
94
+ ---
95
+
96
+ ## Concurrency Red Flags
97
+
98
+ ```bash
99
+ # Find static mut (almost always wrong)
100
+ grep -rn 'static mut' --include='*.rs'
101
+
102
+ # Find blocking calls in async functions
103
+ grep -rn 'std::fs::' --include='*.rs' | grep -v 'test'
104
+ grep -rn 'std::thread::sleep' --include='*.rs'
105
+
106
+ # Find Mutex without Arc in multi-threaded context
107
+ grep -rn 'Mutex::new' --include='*.rs'
108
+ ```
109
+
110
+ **Pattern**: `static mut` — mutable global state (data race risk)
111
+ **Pattern**: `std::fs::` — blocking I/O that may appear in async context
112
+ **Pattern**: `std::thread::sleep` — blocking sleep (use `tokio::time::sleep` in async)
113
+
114
+ ---
115
+
116
+ ## Clippy Lints
117
+
118
+ Run Clippy for automated detection of many patterns above:
119
+
120
+ ```bash
121
+ cargo clippy -- -D warnings
122
+ cargo clippy -- -W clippy::pedantic
123
+ cargo clippy -- -W clippy::nursery
124
+ ```
125
+
126
+ Key Clippy lints that catch issues:
127
+ - `clippy::unwrap_used` — flags unwrap calls
128
+ - `clippy::clone_on_ref_ptr` — unnecessary Arc/Rc clone
129
+ - `clippy::needless_pass_by_value` — should borrow instead
130
+ - `clippy::missing_errors_doc` — public Result fn without doc
131
+ - `clippy::wildcard_enum_match_arm` — catch-all hiding cases
@@ -0,0 +1,242 @@
1
+ # Rust Ownership Deep Dive
2
+
3
+ Advanced ownership patterns, lifetime elision, interior mutability, and pinning.
4
+
5
+ ## Lifetime Elision Rules
6
+
7
+ The compiler applies three rules to infer lifetimes. When they don't resolve, annotate manually.
8
+
9
+ ### Rule 1: Each Reference Parameter Gets Its Own Lifetime
10
+
11
+ ```rust
12
+ // Compiler sees: fn first(s: &str) -> &str
13
+ // Compiler infers: fn first<'a>(s: &'a str) -> &'a str
14
+ fn first(s: &str) -> &str {
15
+ &s[..1]
16
+ }
17
+ ```
18
+
19
+ ### Rule 2: Single Input Lifetime Applies to All Outputs
20
+
21
+ ```rust
22
+ // One input reference — output borrows from it
23
+ fn trim(s: &str) -> &str {
24
+ s.trim()
25
+ }
26
+ ```
27
+
28
+ ### Rule 3: &self Lifetime Applies to All Outputs in Methods
29
+
30
+ ```rust
31
+ impl Config {
32
+ // &self lifetime flows to return
33
+ fn database_url(&self) -> &str {
34
+ &self.db_url
35
+ }
36
+ }
37
+ ```
38
+
39
+ ### When Elision Fails
40
+
41
+ ```rust
42
+ // Two input lifetimes — compiler can't decide which output borrows from
43
+ // Must annotate: output borrows from `a`, not `b`
44
+ fn longest<'a>(a: &'a str, b: &str) -> &'a str {
45
+ if a.len() >= b.len() { a } else { a }
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Interior Mutability
52
+
53
+ Mutate data behind a shared reference when ownership rules are too strict.
54
+
55
+ ### Cell — Copy Types Only
56
+
57
+ ```rust
58
+ use std::cell::Cell;
59
+
60
+ struct Counter {
61
+ count: Cell<u32>, // Mutate through &self
62
+ }
63
+
64
+ impl Counter {
65
+ fn increment(&self) {
66
+ self.count.set(self.count.get() + 1);
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### RefCell — Runtime Borrow Checking
72
+
73
+ ```rust
74
+ use std::cell::RefCell;
75
+
76
+ struct Cache {
77
+ data: RefCell<HashMap<String, String>>,
78
+ }
79
+
80
+ impl Cache {
81
+ fn get_or_insert(&self, key: &str, value: &str) -> String {
82
+ let mut data = self.data.borrow_mut(); // Panics if already borrowed
83
+ data.entry(key.to_string())
84
+ .or_insert_with(|| value.to_string())
85
+ .clone()
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### Mutex — Thread-Safe Interior Mutability
91
+
92
+ ```rust
93
+ use std::sync::Mutex;
94
+
95
+ struct SharedState {
96
+ data: Mutex<Vec<String>>,
97
+ }
98
+
99
+ impl SharedState {
100
+ fn push(&self, item: String) -> Result<(), AppError> {
101
+ let mut data = self.data.lock()
102
+ .map_err(|_| AppError::LockPoisoned)?;
103
+ data.push(item);
104
+ Ok(())
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### Decision Guide
110
+
111
+ | Type | Thread-Safe | Cost | Use Case |
112
+ |------|-------------|------|----------|
113
+ | `Cell<T>` | No | Zero | Copy types, single-threaded |
114
+ | `RefCell<T>` | No | Runtime borrow check | Non-Copy, single-threaded |
115
+ | `Mutex<T>` | Yes | Lock overhead | Multi-threaded mutation |
116
+ | `RwLock<T>` | Yes | Lock overhead | Multi-threaded, read-heavy |
117
+ | `Atomic*` | Yes | Hardware atomic | Counters, flags |
118
+
119
+ ---
120
+
121
+ ## Cow — Clone on Write
122
+
123
+ Defer cloning until mutation is actually needed.
124
+
125
+ ```rust
126
+ use std::borrow::Cow;
127
+
128
+ // Returns borrowed if no processing needed, owned if modified
129
+ fn normalize_path(path: &str) -> Cow<'_, str> {
130
+ if path.contains("//") {
131
+ Cow::Owned(path.replace("//", "/"))
132
+ } else {
133
+ Cow::Borrowed(path)
134
+ }
135
+ }
136
+
137
+ // Function accepts both owned and borrowed transparently
138
+ fn process(input: Cow<'_, str>) {
139
+ println!("{}", input); // No allocation if already borrowed
140
+ }
141
+ ```
142
+
143
+ ### Cow in APIs
144
+
145
+ ```rust
146
+ // Accept Cow for flexible ownership — caller decides allocation
147
+ pub fn log_message(msg: Cow<'_, str>) {
148
+ eprintln!("[LOG] {}", msg);
149
+ }
150
+
151
+ // Caller with borrowed data — zero-copy
152
+ log_message(Cow::Borrowed("static message"));
153
+
154
+ // Caller with owned data — no extra clone
155
+ log_message(Cow::Owned(format!("dynamic: {}", value)));
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Pin for Async and Self-Referential Types
161
+
162
+ ### Why Pin Exists
163
+
164
+ Self-referential structs break if moved in memory. `Pin` guarantees the value won't move.
165
+
166
+ ```rust
167
+ use std::pin::Pin;
168
+ use std::future::Future;
169
+
170
+ // Async functions return self-referential futures
171
+ // Pin ensures the future stays in place while polled
172
+ fn fetch_data(url: &str) -> Pin<Box<dyn Future<Output = Result<Data, Error>> + '_>> {
173
+ Box::pin(async move {
174
+ let response = reqwest::get(url).await?;
175
+ let data = response.json::<Data>().await?;
176
+ Ok(data)
177
+ })
178
+ }
179
+ ```
180
+
181
+ ### Pin in Practice
182
+
183
+ ```rust
184
+ use tokio::pin;
185
+
186
+ async fn process_stream(stream: impl Stream<Item = Data>) {
187
+ // pin! macro pins the stream to the stack
188
+ pin!(stream);
189
+
190
+ while let Some(item) = stream.next().await {
191
+ handle(item).await;
192
+ }
193
+ }
194
+ ```
195
+
196
+ ### When You Need Pin
197
+
198
+ | Scenario | Need Pin? |
199
+ |----------|-----------|
200
+ | Returning `async` blocks as trait objects | Yes |
201
+ | Implementing `Future` manually | Yes |
202
+ | Using `tokio::select!` on futures | Yes (automatically handled) |
203
+ | Normal async/await | No (compiler handles it) |
204
+ | Storing futures in collections | Yes (`Pin<Box<dyn Future>>`) |
205
+
206
+ ---
207
+
208
+ ## Ownership Transfer Patterns
209
+
210
+ ### Take Pattern — Move Out of Option
211
+
212
+ ```rust
213
+ struct Connection {
214
+ session: Option<Session>,
215
+ }
216
+
217
+ impl Connection {
218
+ fn close(&mut self) -> Option<Session> {
219
+ self.session.take() // Moves out, leaves None
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### Swap Pattern — Replace In Place
225
+
226
+ ```rust
227
+ use std::mem;
228
+
229
+ fn rotate_buffer(current: &mut Vec<u8>, new_data: Vec<u8>) -> Vec<u8> {
230
+ mem::replace(current, new_data) // Returns old, installs new
231
+ }
232
+ ```
233
+
234
+ ### Entry Pattern — Conditional Insertion
235
+
236
+ ```rust
237
+ use std::collections::HashMap;
238
+
239
+ fn get_or_create(map: &mut HashMap<String, Vec<Item>>, key: &str) -> &mut Vec<Item> {
240
+ map.entry(key.to_string()).or_insert_with(Vec::new)
241
+ }
242
+ ```
@@ -0,0 +1,210 @@
1
+ # Rust Extended Patterns
2
+
3
+ Extended correct patterns for Rust. Reference from main SKILL.md.
4
+
5
+ ## Typestate Pattern
6
+
7
+ Encode valid state transitions in the type system so invalid sequences don't compile.
8
+
9
+ ```rust
10
+ // States are zero-sized types — no runtime cost
11
+ struct Draft;
12
+ struct Published;
13
+ struct Archived;
14
+
15
+ struct Article<State> {
16
+ title: String,
17
+ body: String,
18
+ _state: std::marker::PhantomData<State>,
19
+ }
20
+
21
+ impl Article<Draft> {
22
+ pub fn new(title: String, body: String) -> Self {
23
+ Article { title, body, _state: std::marker::PhantomData }
24
+ }
25
+
26
+ pub fn publish(self) -> Article<Published> {
27
+ Article { title: self.title, body: self.body, _state: std::marker::PhantomData }
28
+ }
29
+ }
30
+
31
+ impl Article<Published> {
32
+ pub fn archive(self) -> Article<Archived> {
33
+ Article { title: self.title, body: self.body, _state: std::marker::PhantomData }
34
+ }
35
+ }
36
+
37
+ // article.archive() on Draft won't compile — transition enforced at compile time
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Error Handling Hierarchy
43
+
44
+ Layer errors from specific to general using `thiserror` for libraries and `anyhow` for applications.
45
+
46
+ ```rust
47
+ // Library: precise, typed errors
48
+ #[derive(thiserror::Error, Debug)]
49
+ pub enum RepoError {
50
+ #[error("entity {entity} with id {id} not found")]
51
+ NotFound { entity: &'static str, id: String },
52
+ #[error("duplicate key: {0}")]
53
+ Duplicate(String),
54
+ #[error("connection failed")]
55
+ Connection(#[from] sqlx::Error),
56
+ }
57
+
58
+ // Application: ergonomic error propagation
59
+ use anyhow::{Context, Result};
60
+
61
+ fn run() -> Result<()> {
62
+ let config = load_config()
63
+ .context("failed to load configuration")?;
64
+ let db = connect_db(&config.database_url)
65
+ .context("failed to connect to database")?;
66
+ serve(db, config.port)
67
+ .context("server exited with error")
68
+ }
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Trait Objects vs Generics
74
+
75
+ ### Use Generics for Performance (Monomorphization)
76
+
77
+ ```rust
78
+ fn largest<T: PartialOrd>(list: &[T]) -> Option<&T> {
79
+ list.iter().reduce(|a, b| if a >= b { a } else { b })
80
+ }
81
+ ```
82
+
83
+ ### Use Trait Objects for Heterogeneous Collections
84
+
85
+ ```rust
86
+ trait Handler: Send + Sync {
87
+ fn handle(&self, request: &Request) -> Response;
88
+ }
89
+
90
+ struct Router {
91
+ routes: Vec<Box<dyn Handler>>, // Different concrete types in one Vec
92
+ }
93
+ ```
94
+
95
+ ### Decision Guide
96
+
97
+ | Criteria | Generics | Trait Objects |
98
+ |----------|----------|--------------|
99
+ | Known types at compile time | Yes | No |
100
+ | Heterogeneous collection | No | Yes |
101
+ | Performance-critical | Yes | Acceptable overhead |
102
+ | Binary size concern | Increases | Minimal |
103
+
104
+ ---
105
+
106
+ ## Smart Pointers
107
+
108
+ ### Box — Heap Allocation
109
+
110
+ ```rust
111
+ // Recursive types require indirection
112
+ enum List<T> {
113
+ Cons(T, Box<List<T>>),
114
+ Nil,
115
+ }
116
+ ```
117
+
118
+ ### Rc/Arc — Shared Ownership
119
+
120
+ ```rust
121
+ use std::sync::Arc;
122
+
123
+ // Shared read-only config across threads
124
+ let config = Arc::new(load_config()?);
125
+ let config_clone = Arc::clone(&config);
126
+ tokio::spawn(async move {
127
+ use_config(&config_clone).await;
128
+ });
129
+ ```
130
+
131
+ ### When to Use Each
132
+
133
+ | Pointer | Use Case |
134
+ |---------|----------|
135
+ | `Box<T>` | Single owner, heap allocation, recursive types |
136
+ | `Rc<T>` | Multiple owners, single-threaded |
137
+ | `Arc<T>` | Multiple owners, multi-threaded |
138
+ | `Cow<'a, T>` | Clone-on-write, flexible borrowing |
139
+
140
+ ---
141
+
142
+ ## From/Into Conversions
143
+
144
+ ```rust
145
+ // Implement From for automatic Into
146
+ impl From<CreateUserRequest> for User {
147
+ fn from(req: CreateUserRequest) -> Self {
148
+ User {
149
+ id: Uuid::new_v4(),
150
+ name: req.name,
151
+ email: req.email,
152
+ created_at: Utc::now(),
153
+ }
154
+ }
155
+ }
156
+
157
+ // Callers get Into for free
158
+ fn save_user(user: impl Into<User>) -> Result<(), DbError> {
159
+ let user: User = user.into();
160
+ // ...
161
+ Ok(())
162
+ }
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Derive and Trait Best Practices
168
+
169
+ ```rust
170
+ // Derive the standard set for data types
171
+ #[derive(Debug, Clone, PartialEq, Eq, Hash)]
172
+ pub struct UserId(String);
173
+
174
+ // Derive serde for serialization boundaries
175
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
176
+ pub struct ApiResponse<T> {
177
+ pub data: T,
178
+ pub metadata: Metadata,
179
+ }
180
+ ```
181
+
182
+ ### Trait Implementation Order Convention
183
+
184
+ 1. Standard library traits (`Debug`, `Display`, `Clone`, `PartialEq`)
185
+ 2. Conversion traits (`From`, `Into`, `TryFrom`)
186
+ 3. Iterator traits (`Iterator`, `IntoIterator`)
187
+ 4. Serde traits (`Serialize`, `Deserialize`)
188
+ 5. Custom traits (domain-specific)
189
+
190
+ ---
191
+
192
+ ## Module Organization
193
+
194
+ ```
195
+ src/
196
+ ├── lib.rs # Public API re-exports
197
+ ├── error.rs # Crate-level error types
198
+ ├── domain/
199
+ │ ├── mod.rs # Domain re-exports
200
+ │ ├── user.rs # User entity and logic
201
+ │ └── order.rs # Order entity and logic
202
+ ├── repo/
203
+ │ ├── mod.rs # Repository trait definitions
204
+ │ └── postgres.rs # Concrete implementation
205
+ └── api/
206
+ ├── mod.rs # Route registration
207
+ └── handlers.rs # HTTP handlers
208
+ ```
209
+
210
+ Keep `lib.rs` thin — re-export only the public API. Internal modules use `pub(crate)`.