agy-superpowers 5.2.2 → 5.2.3

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 (220) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/scratch-scripts.md +37 -0
  4. package/template/agent/rules/superpowers.md +4 -51
  5. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  6. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  7. package/template/agent/skills/api-design/SKILL.md +0 -193
  8. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  9. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  10. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  11. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  12. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  13. package/template/agent/skills/community-manager/SKILL.md +0 -115
  14. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  15. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  16. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  17. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  18. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  19. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  20. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  21. package/template/agent/skills/game-design/SKILL.md +0 -194
  22. package/template/agent/skills/game-developer/SKILL.md +0 -175
  23. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  24. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  25. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  26. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  27. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  28. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  29. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  30. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  31. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  32. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  33. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  34. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  35. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  36. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  37. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  38. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  39. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  40. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  41. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  42. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  43. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  44. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  45. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  46. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  47. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  48. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  53. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  54. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  55. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  56. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  57. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  58. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  59. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  60. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  61. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  62. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  63. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  68. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  69. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  70. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  71. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  72. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  73. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  74. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  75. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  76. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  77. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  78. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  83. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  84. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  85. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  86. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  87. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  88. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  89. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  90. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  91. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  92. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  93. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  94. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  95. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  96. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  97. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  98. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  99. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  100. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  101. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  102. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  103. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  104. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  106. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  107. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  108. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  109. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  110. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  111. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  113. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  114. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  115. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  116. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  117. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  118. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  119. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  120. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  121. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  122. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  123. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  124. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  125. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  126. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  127. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  132. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  133. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  134. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  135. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  136. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  137. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  138. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  139. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  140. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  141. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  148. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  149. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  150. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  151. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  152. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  153. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  154. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  155. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  156. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  157. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  158. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  160. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  161. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  162. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  163. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  164. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  165. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  166. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  167. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  168. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  169. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  170. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  172. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  173. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  174. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  175. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  176. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  177. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  179. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  180. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  181. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  182. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  183. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  184. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  185. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  186. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  187. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  188. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  189. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  190. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  191. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  192. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  193. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  194. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  195. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  196. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  197. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  198. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  199. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  200. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  201. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  202. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  203. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  204. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  207. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  208. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  210. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  211. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  212. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  213. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  214. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  215. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  216. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  217. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  218. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  219. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  220. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,125 +0,0 @@
1
- # anti-index-over-iter
2
-
3
- > Don't use indexing when iterators work
4
-
5
- ## Why It Matters
6
-
7
- Manual indexing (`for i in 0..len`) requires bounds checks on every access, prevents SIMD optimization, and introduces off-by-one error risks. Iterators eliminate these issues and are more idiomatic Rust.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Manual indexing - bounds checked every access
13
- fn sum_squares(data: &[i32]) -> i64 {
14
- let mut result = 0i64;
15
- for i in 0..data.len() {
16
- result += (data[i] as i64) * (data[i] as i64);
17
- }
18
- result
19
- }
20
-
21
- // Index-based with multiple arrays
22
- fn dot_product(a: &[f64], b: &[f64]) -> f64 {
23
- let mut sum = 0.0;
24
- for i in 0..a.len().min(b.len()) {
25
- sum += a[i] * b[i];
26
- }
27
- sum
28
- }
29
-
30
- // Mutation with indices
31
- fn normalize(data: &mut [f64]) {
32
- let max = data.iter().cloned().fold(0.0, f64::max);
33
- for i in 0..data.len() {
34
- data[i] /= max;
35
- }
36
- }
37
- ```
38
-
39
- ## Good
40
-
41
- ```rust
42
- // Iterator - no bounds checks, SIMD-friendly
43
- fn sum_squares(data: &[i32]) -> i64 {
44
- data.iter()
45
- .map(|&x| (x as i64) * (x as i64))
46
- .sum()
47
- }
48
-
49
- // Zip - handles length mismatch automatically
50
- fn dot_product(a: &[f64], b: &[f64]) -> f64 {
51
- a.iter()
52
- .zip(b.iter())
53
- .map(|(&x, &y)| x * y)
54
- .sum()
55
- }
56
-
57
- // Mutable iteration
58
- fn normalize(data: &mut [f64]) {
59
- let max = data.iter().cloned().fold(0.0, f64::max);
60
- for x in data.iter_mut() {
61
- *x /= max;
62
- }
63
- }
64
- ```
65
-
66
- ## When Indices Are Needed
67
-
68
- Sometimes you genuinely need indices:
69
-
70
- ```rust
71
- // Need index in output
72
- for (i, item) in items.iter().enumerate() {
73
- println!("{}: {}", i, item);
74
- }
75
-
76
- // Non-sequential access
77
- for i in (0..len).step_by(2) {
78
- swap(&mut data[i], &mut data[i + 1]);
79
- }
80
-
81
- // Multi-dimensional iteration
82
- for i in 0..rows {
83
- for j in 0..cols {
84
- matrix[i][j] = i * cols + j;
85
- }
86
- }
87
- ```
88
-
89
- ## Comparison
90
-
91
- | Pattern | Bounds Checks | SIMD | Safety |
92
- |---------|---------------|------|--------|
93
- | `for i in 0..len { data[i] }` | Every access | Limited | Off-by-one risk |
94
- | `for x in &data` | None | Good | Safe |
95
- | `for x in data.iter()` | None | Good | Safe |
96
- | `data.iter().enumerate()` | None | Good | Safe |
97
-
98
- ## Common Conversions
99
-
100
- | Index Pattern | Iterator Pattern |
101
- |---------------|------------------|
102
- | `for i in 0..v.len()` | `for x in &v` |
103
- | `v[0]` | `v.first()` |
104
- | `v[v.len()-1]` | `v.last()` |
105
- | `for i in 0..a.len() { a[i] + b[i] }` | `a.iter().zip(&b)` |
106
- | `for i in 0..v.len() { v[i] *= 2 }` | `for x in &mut v { *x *= 2 }` |
107
-
108
- ## Performance Note
109
-
110
- ```rust
111
- // Iterator version can auto-vectorize
112
- let sum: i32 = data.iter().sum();
113
-
114
- // Manual indexing prevents vectorization
115
- let mut sum = 0;
116
- for i in 0..data.len() {
117
- sum += data[i];
118
- }
119
- ```
120
-
121
- ## See Also
122
-
123
- - [perf-iter-over-index](./perf-iter-over-index.md) - Performance details
124
- - [opt-bounds-check](./opt-bounds-check.md) - Bounds check elimination
125
- - [perf-iter-lazy](./perf-iter-lazy.md) - Lazy iterators
@@ -1,127 +0,0 @@
1
- # anti-lock-across-await
2
-
3
- > Don't hold locks across await points
4
-
5
- ## Why It Matters
6
-
7
- Holding a `Mutex` or `RwLock` guard across an `.await` causes the lock to be held while the task is suspended. Other tasks waiting for the lock block indefinitely. With `std::sync::Mutex`, this is even worse—it can deadlock the entire runtime.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use std::sync::Mutex;
13
- use tokio::sync::Mutex as AsyncMutex;
14
-
15
- // DEADLOCK RISK: std::sync::Mutex held across await
16
- async fn bad_std_mutex(data: &Mutex<Vec<i32>>) {
17
- let mut guard = data.lock().unwrap();
18
- do_async_work().await; // Lock held during await!
19
- guard.push(42);
20
- }
21
-
22
- // BLOCKS OTHER TASKS: tokio Mutex held across await
23
- async fn bad_async_mutex(data: &AsyncMutex<Vec<i32>>) {
24
- let mut guard = data.lock().await;
25
- slow_network_call().await; // Lock held for entire call!
26
- guard.push(42);
27
- }
28
- ```
29
-
30
- ## Good
31
-
32
- ```rust
33
- use std::sync::Mutex;
34
- use tokio::sync::Mutex as AsyncMutex;
35
-
36
- // Release lock before await
37
- async fn good_approach(data: &Mutex<Vec<i32>>) {
38
- let value = {
39
- let guard = data.lock().unwrap();
40
- guard.last().copied() // Extract what you need
41
- }; // Lock released here
42
-
43
- let result = do_async_work(value).await;
44
-
45
- {
46
- let mut guard = data.lock().unwrap();
47
- guard.push(result);
48
- }
49
- }
50
-
51
- // Minimize lock scope with async mutex
52
- async fn good_async_mutex(data: &AsyncMutex<Vec<i32>>, item: i32) {
53
- // Quick lock, quick release
54
- data.lock().await.push(item);
55
-
56
- // Async work without lock
57
- let result = slow_network_call().await;
58
-
59
- // Quick lock again
60
- data.lock().await.push(result);
61
- }
62
- ```
63
-
64
- ## Pattern: Clone Before Await
65
-
66
- ```rust
67
- async fn process(data: &AsyncMutex<Config>) -> Result<()> {
68
- // Clone inside lock scope
69
- let config = data.lock().await.clone();
70
-
71
- // Now use config freely across awaits
72
- let result = fetch_data(&config.url).await?;
73
- process_result(&config, result).await?;
74
-
75
- Ok(())
76
- }
77
- ```
78
-
79
- ## Pattern: Restructure to Avoid Lock
80
-
81
- ```rust
82
- // Instead of locking a shared map
83
- struct Service {
84
- data: AsyncMutex<HashMap<String, Data>>,
85
- }
86
-
87
- // Use channels or owned data
88
- struct BetterService {
89
- // Each task owns its data via channels
90
- sender: mpsc::Sender<Request>,
91
- }
92
-
93
- impl BetterService {
94
- async fn request(&self, key: String) -> Data {
95
- let (tx, rx) = oneshot::channel();
96
- self.sender.send(Request { key, respond: tx }).await?;
97
- rx.await?
98
- }
99
- }
100
- ```
101
-
102
- ## What Can Cross Await
103
-
104
- | Type | Safe Across Await? |
105
- |------|--------------------|
106
- | `std::sync::Mutex` guard | **NO** - can deadlock |
107
- | `std::sync::RwLock` guard | **NO** - can deadlock |
108
- | `tokio::sync::Mutex` guard | Allowed but blocks tasks |
109
- | `tokio::sync::RwLock` guard | Allowed but blocks tasks |
110
- | Owned values | Yes |
111
- | `Arc<T>` | Yes |
112
- | References | Depends on lifetime |
113
-
114
- ## Detection
115
-
116
- ```toml
117
- # Cargo.toml
118
- [lints.clippy]
119
- await_holding_lock = "deny"
120
- await_holding_refcell_ref = "deny"
121
- ```
122
-
123
- ## See Also
124
-
125
- - [async-no-lock-await](./async-no-lock-await.md) - Async lock patterns
126
- - [async-clone-before-await](./async-clone-before-await.md) - Clone pattern
127
- - [own-mutex-interior](./own-mutex-interior.md) - Mutex usage
@@ -1,120 +0,0 @@
1
- # anti-over-abstraction
2
-
3
- > Don't over-abstract with excessive generics
4
-
5
- ## Why It Matters
6
-
7
- Generics and traits are powerful but come at a cost: compile times, binary size, and cognitive load. Over-abstraction—making everything generic "for flexibility"—often adds complexity without benefit. Start concrete; generalize when you have real use cases.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Overly generic for a simple function
13
- fn add<T, U, R>(a: T, b: U) -> R
14
- where
15
- T: Into<R>,
16
- U: Into<R>,
17
- R: std::ops::Add<Output = R>,
18
- {
19
- a.into() + b.into()
20
- }
21
-
22
- // Just call add(1, 2) - why make it this complex?
23
-
24
- // Trait explosion
25
- trait Readable {}
26
- trait Writable {}
27
- trait ReadWritable: Readable + Writable {}
28
- trait AsyncReadable {}
29
- trait AsyncWritable {}
30
- trait AsyncReadWritable: AsyncReadable + AsyncWritable {}
31
-
32
- // Abstract factory pattern (Java flashback)
33
- trait Factory<T> {
34
- fn create(&self) -> T;
35
- }
36
- trait FactoryFactory<F: Factory<T>, T> {
37
- fn create_factory(&self) -> F;
38
- }
39
- ```
40
-
41
- ## Good
42
-
43
- ```rust
44
- // Concrete implementation - clear and simple
45
- fn add_i32(a: i32, b: i32) -> i32 {
46
- a + b
47
- }
48
-
49
- // Generic when actually needed (e.g., library code)
50
- fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
51
- a + b
52
- }
53
-
54
- // Simple traits for actual polymorphism needs
55
- trait Storage {
56
- fn save(&self, key: &str, value: &[u8]) -> Result<(), Error>;
57
- fn load(&self, key: &str) -> Result<Vec<u8>, Error>;
58
- }
59
-
60
- // Concrete types first
61
- struct FileStorage { path: PathBuf }
62
- struct MemoryStorage { data: HashMap<String, Vec<u8>> }
63
- ```
64
-
65
- ## Signs of Over-Abstraction
66
-
67
- | Sign | Symptom |
68
- |------|---------|
69
- | Single implementation | Generic trait with only one impl |
70
- | Type parameter soup | `T, U, V, W` everywhere |
71
- | Marker traits | Traits with no methods |
72
- | Deep trait bounds | `where T: A + B + C + D + E` |
73
- | Phantom generics | Type parameters not used meaningfully |
74
-
75
- ## When to Generalize
76
-
77
- Generalize when:
78
- - You have 2+ concrete types that share behavior
79
- - You're writing library code for public consumption
80
- - Performance requires static dispatch
81
- - The abstraction simplifies the API
82
-
83
- Don't generalize when:
84
- - You "might need it later" (YAGNI)
85
- - Only one type will ever implement it
86
- - It makes code harder to understand
87
-
88
- ## Rule of Three
89
-
90
- Wait until you have three similar concrete implementations before abstracting:
91
-
92
- ```rust
93
- // Version 1: Just FileStorage
94
- struct FileStorage { /* ... */ }
95
-
96
- // Version 2: Added MemoryStorage, similar interface
97
- struct MemoryStorage { /* ... */ }
98
-
99
- // Version 3: Now Redis too - time to abstract
100
- trait Storage {
101
- fn save(&self, key: &str, value: &[u8]) -> Result<()>;
102
- fn load(&self, key: &str) -> Result<Vec<u8>>;
103
- }
104
- ```
105
-
106
- ## Prefer Concrete Types in Private Code
107
-
108
- ```rust
109
- // Internal function - concrete type is fine
110
- fn process_orders(db: &PostgresDb, orders: Vec<Order>) { }
111
-
112
- // Public API - might benefit from abstraction
113
- pub fn process_orders<S: Storage>(storage: &S, orders: Vec<Order>) { }
114
- ```
115
-
116
- ## See Also
117
-
118
- - [type-generic-bounds](./type-generic-bounds.md) - Minimal bounds
119
- - [api-sealed-trait](./api-sealed-trait.md) - Controlled extension
120
- - [anti-type-erasure](./anti-type-erasure.md) - When Box<dyn> is wrong
@@ -1,131 +0,0 @@
1
- # anti-panic-expected
2
-
3
- > Don't panic on expected or recoverable errors
4
-
5
- ## Why It Matters
6
-
7
- Panics crash the program. They're for unrecoverable situations—bugs, corrupted state, invariant violations. Using panic for expected conditions (network failures, file not found, invalid input) makes programs fragile and forces callers to catch panics or die.
8
-
9
- Use `Result` for recoverable errors.
10
-
11
- ## Bad
12
-
13
- ```rust
14
- // Network failures are expected
15
- fn fetch_data(url: &str) -> Data {
16
- let response = reqwest::blocking::get(url)
17
- .expect("network error"); // Crashes on timeout
18
- response.json().expect("invalid json") // Crashes on bad response
19
- }
20
-
21
- // User input is often invalid
22
- fn parse_config(input: &str) -> Config {
23
- toml::from_str(input).expect("invalid config") // Crashes on typo
24
- }
25
-
26
- // Files may not exist
27
- fn load_settings() -> Settings {
28
- let content = fs::read_to_string("settings.json")
29
- .expect("settings not found"); // Crashes if missing
30
- serde_json::from_str(&content).expect("invalid settings")
31
- }
32
-
33
- // Custom panic for validation
34
- fn process_age(age: i32) {
35
- if age < 0 {
36
- panic!("age cannot be negative"); // Should return error
37
- }
38
- }
39
- ```
40
-
41
- ## Good
42
-
43
- ```rust
44
- // Return errors for expected failures
45
- fn fetch_data(url: &str) -> Result<Data, FetchError> {
46
- let response = reqwest::blocking::get(url)
47
- .context("failed to connect")?;
48
- let data = response.json()
49
- .context("failed to parse response")?;
50
- Ok(data)
51
- }
52
-
53
- // Validate and return Result
54
- fn parse_config(input: &str) -> Result<Config, ConfigError> {
55
- toml::from_str(input).map_err(ConfigError::Parse)
56
- }
57
-
58
- // Handle missing files gracefully
59
- fn load_settings() -> Result<Settings, SettingsError> {
60
- let content = fs::read_to_string("settings.json")?;
61
- let settings = serde_json::from_str(&content)?;
62
- Ok(settings)
63
- }
64
-
65
- // Return error for validation failure
66
- fn process_age(age: i32) -> Result<(), ValidationError> {
67
- if age < 0 {
68
- return Err(ValidationError::NegativeAge);
69
- }
70
- Ok(())
71
- }
72
- ```
73
-
74
- ## When to Panic
75
-
76
- Panic IS appropriate for:
77
-
78
- ```rust
79
- // Bug detection - invariant violated
80
- fn get_unchecked(&self, index: usize) -> &T {
81
- assert!(index < self.len(), "index out of bounds - this is a bug");
82
- unsafe { self.data.get_unchecked(index) }
83
- }
84
-
85
- // Unrecoverable state
86
- fn init() {
87
- if !CAN_PROCEED {
88
- panic!("system requirements not met");
89
- }
90
- }
91
-
92
- // Tests
93
- #[test]
94
- fn test_fails() {
95
- panic!("expected panic in test");
96
- }
97
- ```
98
-
99
- ## Decision Guide
100
-
101
- | Condition | Action |
102
- |-----------|--------|
103
- | Invalid user input | Return `Err` |
104
- | Network failure | Return `Err` |
105
- | File not found | Return `Err` |
106
- | Malformed data | Return `Err` |
107
- | Bug/impossible state | `panic!` or `unreachable!` |
108
- | Failed assertion in test | `panic!` |
109
- | Unrecoverable init failure | `panic!` |
110
-
111
- ## Anti-pattern: panic! for Control Flow
112
-
113
- ```rust
114
- // BAD: Using panic for control flow
115
- fn find_or_die(items: &[Item], id: u64) -> &Item {
116
- items.iter()
117
- .find(|i| i.id == id)
118
- .unwrap_or_else(|| panic!("item {} not found", id))
119
- }
120
-
121
- // GOOD: Return Option or Result
122
- fn find(items: &[Item], id: u64) -> Option<&Item> {
123
- items.iter().find(|i| i.id == id)
124
- }
125
- ```
126
-
127
- ## See Also
128
-
129
- - [err-result-over-panic](./err-result-over-panic.md) - Use Result
130
- - [anti-unwrap-abuse](./anti-unwrap-abuse.md) - Unwrap anti-pattern
131
- - [err-expect-bugs-only](./err-expect-bugs-only.md) - When to expect
@@ -1,156 +0,0 @@
1
- # anti-premature-optimize
2
-
3
- > Don't optimize before profiling
4
-
5
- ## Why It Matters
6
-
7
- Premature optimization wastes time, complicates code, and often targets the wrong bottlenecks. Most code isn't performance-critical; the hot 10% matters. Profile first, then optimize the actual bottlenecks with data-driven decisions.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // "Optimizing" without measurement
13
- fn sum(data: &[i32]) -> i32 {
14
- // Using unsafe "for performance" without profiling
15
- unsafe {
16
- let mut sum = 0;
17
- for i in 0..data.len() {
18
- sum += *data.get_unchecked(i);
19
- }
20
- sum
21
- }
22
- }
23
-
24
- // Complex caching with no evidence it's needed
25
- lazy_static! {
26
- static ref CACHE: RwLock<HashMap<String, Arc<Result>>> =
27
- RwLock::new(HashMap::new());
28
- }
29
-
30
- // Hand-rolled data structures "for speed"
31
- struct MyVec<T> {
32
- ptr: *mut T,
33
- len: usize,
34
- cap: usize,
35
- }
36
- ```
37
-
38
- ## Good
39
-
40
- ```rust
41
- // Simple, idiomatic - let compiler optimize
42
- fn sum(data: &[i32]) -> i32 {
43
- data.iter().sum()
44
- }
45
-
46
- // Profile, then optimize if needed
47
- fn sum_optimized(data: &[i32]) -> i32 {
48
- // After profiling showed this is a bottleneck,
49
- // we measured that manual SIMD gives 3x speedup
50
- #[cfg(target_arch = "x86_64")]
51
- {
52
- // SIMD implementation with benchmark data
53
- }
54
- #[cfg(not(target_arch = "x86_64"))]
55
- {
56
- data.iter().sum()
57
- }
58
- }
59
-
60
- // Use standard library - it's well-optimized
61
- let cache: HashMap<String, Result> = HashMap::new();
62
- ```
63
-
64
- ## Profiling Workflow
65
-
66
- ```bash
67
- # 1. Write correct code first
68
- cargo build --release
69
-
70
- # 2. Profile with real workloads
71
- cargo flamegraph --bin my_app -- --real-args
72
- # or
73
- cargo bench
74
-
75
- # 3. Identify hotspots (top 10% of time)
76
-
77
- # 4. Measure before optimizing
78
- # 5. Optimize ONE thing
79
- # 6. Measure after - verify improvement
80
- # 7. Repeat if still slow
81
- ```
82
-
83
- ## Optimization Principles
84
-
85
- | Do | Don't |
86
- |----|-------|
87
- | Profile first | Guess at bottlenecks |
88
- | Optimize hotspots | Optimize everything |
89
- | Measure improvement | Assume it's faster |
90
- | Keep it simple | Add complexity speculatively |
91
- | Trust the compiler | Outsmart the compiler |
92
-
93
- ## When to Optimize
94
-
95
- ```rust
96
- // AFTER profiling shows this is 40% of runtime
97
- #[inline]
98
- fn hot_function(data: &[u8]) -> u64 {
99
- // Optimized implementation justified by benchmarks
100
- }
101
-
102
- // Clear, measurable benefit documented
103
- /// Pre-allocated buffer for repeated formatting.
104
- /// Benchmarks show 3x speedup for >1000 calls/sec workloads.
105
- struct FormatterPool {
106
- buffers: Vec<String>,
107
- }
108
- ```
109
-
110
- ## Common Premature Optimizations
111
-
112
- | Premature | Reality |
113
- |-----------|---------|
114
- | `#[inline(always)]` everywhere | Compiler usually knows better |
115
- | `unsafe` for bounds check removal | Iterator does this safely |
116
- | Custom allocator | Default is usually fine |
117
- | Object pooling | Allocator is fast enough |
118
- | Manual SIMD | Auto-vectorization works |
119
-
120
- ## Profile Tools
121
-
122
- ```bash
123
- # Sampling profiler
124
- perf record ./target/release/app && perf report
125
-
126
- # Flamegraph
127
- cargo install flamegraph
128
- cargo flamegraph
129
-
130
- # Criterion benchmarks
131
- cargo bench
132
-
133
- # Memory profiling
134
- valgrind --tool=massif ./target/release/app
135
- ```
136
-
137
- ## Document Optimizations
138
-
139
- ```rust
140
- /// Lookup table for fast character classification.
141
- ///
142
- /// # Performance
143
- ///
144
- /// Benchmarked with criterion (benchmarks/char_class.rs):
145
- /// - Table lookup: 2.3ns/op
146
- /// - Match statement: 8.7ns/op
147
- ///
148
- /// Justified for hot path in parser (called 10M+ times).
149
- static CHAR_CLASS: [CharClass; 256] = [/* ... */];
150
- ```
151
-
152
- ## See Also
153
-
154
- - [perf-profile-first](./perf-profile-first.md) - Profile before optimize
155
- - [test-criterion-bench](./test-criterion-bench.md) - Benchmarking
156
- - [opt-inline-small](./opt-inline-small.md) - Inline guidelines