agy-superpowers 5.2.1 → 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 (233) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/patches/skills-patches.md +23 -0
  4. package/template/agent/rules/scratch-scripts.md +37 -0
  5. package/template/agent/rules/superpowers.md +6 -50
  6. package/template/agent/skills/brainstorming/SKILL.md +4 -3
  7. package/template/agent/skills/brainstorming/visual-companion.md +2 -3
  8. package/template/agent/skills/finishing-a-development-branch/SKILL.md +11 -16
  9. package/template/agent/skills/subagent-driven-development/SKILL.md +16 -0
  10. package/template/agent/skills/subagent-driven-development/implementer-prompt.md +4 -3
  11. package/template/agent/skills/using-git-worktrees/SKILL.md +3 -2
  12. package/template/agent/skills/using-superpowers/SKILL.md +8 -6
  13. package/template/agent/skills/using-superpowers/references/copilot-tools.md +52 -0
  14. package/template/agent/skills/writing-plans/SKILL.md +5 -3
  15. package/template/agent/skills/writing-skills/SKILL.md +1 -1
  16. package/template/agent/superpowers-version.json +2 -2
  17. package/template/agent/tmp/agent-config-backup.yml +9 -0
  18. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  19. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  20. package/template/agent/skills/api-design/SKILL.md +0 -193
  21. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  22. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  23. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  24. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  25. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  26. package/template/agent/skills/community-manager/SKILL.md +0 -115
  27. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  28. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  29. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  30. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  31. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  32. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  33. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  34. package/template/agent/skills/game-design/SKILL.md +0 -194
  35. package/template/agent/skills/game-developer/SKILL.md +0 -175
  36. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  37. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  38. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  39. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  40. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  41. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  42. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  43. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  44. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  45. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  46. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  47. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  48. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  49. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  50. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  64. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  79. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  80. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  94. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  95. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  105. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  106. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  117. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  118. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  128. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  129. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  143. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  144. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  159. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  160. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  171. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  172. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  183. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  184. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  194. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  195. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  206. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  218. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  228. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  229. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  230. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  231. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  232. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  233. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,133 +0,0 @@
1
- # perf-collect-into
2
-
3
- > Use collect_into for reusing containers
4
-
5
- ## Why It Matters
6
-
7
- `collect_into()` (stabilized in Rust 1.83) allows collecting iterator results into an existing collection, reusing its allocation. This avoids the allocation that `collect()` would make for a new collection.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Allocates new Vec each time
13
- fn process_batches(batches: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
14
- batches.into_iter()
15
- .map(|batch| {
16
- batch.into_iter()
17
- .filter(|x| *x > 0)
18
- .collect::<Vec<_>>() // New allocation per batch
19
- })
20
- .collect()
21
- }
22
-
23
- // Can't reuse cleared buffer
24
- fn filter_loop(data: &[Vec<i32>]) {
25
- for batch in data {
26
- let filtered: Vec<_> = batch.iter()
27
- .filter(|&&x| x > 0)
28
- .copied()
29
- .collect(); // New allocation each iteration
30
- process(&filtered);
31
- }
32
- }
33
- ```
34
-
35
- ## Good
36
-
37
- ```rust
38
- // Reuse buffer with collect_into
39
- fn filter_loop(data: &[Vec<i32>]) {
40
- let mut buffer = Vec::new();
41
-
42
- for batch in data {
43
- buffer.clear(); // Keep allocation
44
- batch.iter()
45
- .filter(|&&x| x > 0)
46
- .copied()
47
- .collect_into(&mut buffer);
48
- process(&buffer);
49
- }
50
- }
51
-
52
- // Also works with extend pattern
53
- fn filter_loop_extend(data: &[Vec<i32>]) {
54
- let mut buffer = Vec::new();
55
-
56
- for batch in data {
57
- buffer.clear();
58
- buffer.extend(
59
- batch.iter()
60
- .filter(|&&x| x > 0)
61
- .copied()
62
- );
63
- process(&buffer);
64
- }
65
- }
66
- ```
67
-
68
- ## Pre-1.83 Alternative: extend
69
-
70
- Before `collect_into()` was stabilized, use `extend()`:
71
-
72
- ```rust
73
- fn reuse_buffer(data: &[Vec<i32>]) {
74
- let mut buffer = Vec::new();
75
-
76
- for batch in data {
77
- buffer.clear();
78
- buffer.extend(batch.iter().filter(|&&x| x > 0).copied());
79
- process(&buffer);
80
- }
81
- }
82
- ```
83
-
84
- ## Pattern: Transform and Reuse
85
-
86
- ```rust
87
- fn transform_batches(batches: &[Vec<RawData>]) -> Vec<ProcessedData> {
88
- let mut temp = Vec::new();
89
- let mut all_results = Vec::new();
90
-
91
- for batch in batches {
92
- temp.clear();
93
- batch.iter()
94
- .map(ProcessedData::from)
95
- .collect_into(&mut temp);
96
-
97
- // Process temp, append to results
98
- all_results.extend(temp.drain(..).filter(|p| p.is_valid()));
99
- }
100
-
101
- all_results
102
- }
103
- ```
104
-
105
- ## Supported Collections
106
-
107
- `collect_into()` works with any type implementing `Extend`:
108
-
109
- ```rust
110
- use std::collections::{HashSet, HashMap, VecDeque};
111
-
112
- let mut vec = Vec::new();
113
- let mut set = HashSet::new();
114
- let mut deque = VecDeque::new();
115
-
116
- (0..10).collect_into(&mut vec);
117
- (0..10).collect_into(&mut set);
118
- (0..10).collect_into(&mut deque);
119
- ```
120
-
121
- ## Comparison
122
-
123
- | Method | Allocation | Buffer Reuse |
124
- |--------|------------|--------------|
125
- | `.collect()` | New each time | No |
126
- | `.collect_into(&mut buf)` | Reuses buffer | Yes |
127
- | `buf.extend(iter)` | Reuses buffer | Yes |
128
-
129
- ## See Also
130
-
131
- - [perf-drain-reuse](./perf-drain-reuse.md) - Drain for reuse
132
- - [mem-reuse-collections](./mem-reuse-collections.md) - Collection reuse
133
- - [perf-extend-batch](./perf-extend-batch.md) - Batch extensions
@@ -1,120 +0,0 @@
1
- # perf-collect-once
2
-
3
- > Don't collect intermediate iterators
4
-
5
- ## Why It Matters
6
-
7
- Each `.collect()` allocates a new collection. Chaining multiple operations with intermediate collections wastes memory and CPU cycles. Keep iterator chains lazy and collect only once at the end.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Three allocations, three passes
13
- fn process_users(users: Vec<User>) -> Vec<String> {
14
- let active: Vec<_> = users.into_iter()
15
- .filter(|u| u.is_active)
16
- .collect();
17
-
18
- let verified: Vec<_> = active.into_iter()
19
- .filter(|u| u.is_verified)
20
- .collect();
21
-
22
- verified.into_iter()
23
- .map(|u| u.name)
24
- .collect()
25
- }
26
-
27
- // Collecting to count
28
- fn count_valid(items: &[Item]) -> usize {
29
- items.iter()
30
- .filter(|i| i.is_valid())
31
- .collect::<Vec<_>>() // Unnecessary!
32
- .len()
33
- }
34
- ```
35
-
36
- ## Good
37
-
38
- ```rust
39
- // One allocation, one pass
40
- fn process_users(users: Vec<User>) -> Vec<String> {
41
- users.into_iter()
42
- .filter(|u| u.is_active)
43
- .filter(|u| u.is_verified)
44
- .map(|u| u.name)
45
- .collect()
46
- }
47
-
48
- // No allocation needed
49
- fn count_valid(items: &[Item]) -> usize {
50
- items.iter()
51
- .filter(|i| i.is_valid())
52
- .count()
53
- }
54
- ```
55
-
56
- ## Pattern: Deferred Collection
57
-
58
- ```rust
59
- // Create the iterator chain
60
- fn prepare_data(raw: Vec<RawData>) -> impl Iterator<Item = ProcessedData> {
61
- raw.into_iter()
62
- .filter(|d| d.is_valid())
63
- .map(ProcessedData::from)
64
- }
65
-
66
- // Collect only when needed
67
- let data: Vec<_> = prepare_data(input).collect();
68
-
69
- // Or consume without collecting
70
- prepare_data(input).for_each(|d| process(d));
71
- ```
72
-
73
- ## When Intermediate Collection Is Needed
74
-
75
- ```rust
76
- // Need to iterate multiple times
77
- let items: Vec<_> = data.iter()
78
- .filter(|x| x.is_valid())
79
- .collect();
80
-
81
- let count = items.len();
82
- let first = items.first();
83
- for item in &items {
84
- process(item);
85
- }
86
-
87
- // Need to sort (requires concrete collection)
88
- let mut sorted: Vec<_> = data.iter()
89
- .filter(|x| x.is_active)
90
- .collect();
91
- sorted.sort_by_key(|x| x.priority);
92
- ```
93
-
94
- ## Comparison
95
-
96
- | Approach | Allocations | Passes | Memory |
97
- |----------|-------------|--------|--------|
98
- | Multiple `.collect()` | N | N | O(N × data) |
99
- | Single chain + `.collect()` | 1 | 1 | O(data) |
100
- | No `.collect()` (streaming) | 0 | 1 | O(1) |
101
-
102
- ## Pattern: Collect with Capacity
103
-
104
- When you must collect, pre-allocate:
105
-
106
- ```rust
107
- // With estimated capacity
108
- let mut result = Vec::with_capacity(items.len());
109
- result.extend(
110
- items.iter()
111
- .filter(|x| x.is_valid())
112
- .map(|x| x.clone())
113
- );
114
- ```
115
-
116
- ## See Also
117
-
118
- - [perf-iter-lazy](./perf-iter-lazy.md) - Keep iterators lazy
119
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocate collections
120
- - [anti-collect-intermediate](./anti-collect-intermediate.md) - Anti-pattern
@@ -1,137 +0,0 @@
1
- # perf-drain-reuse
2
-
3
- > Use drain to reuse allocations
4
-
5
- ## Why It Matters
6
-
7
- `drain()` removes elements from a collection while keeping its allocated capacity. This allows reusing the same allocation across iterations, avoiding repeated allocate/deallocate cycles in loops.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Allocates new Vec every iteration
13
- fn process_batches(data: Vec<Item>) {
14
- let mut remaining = data;
15
-
16
- while !remaining.is_empty() {
17
- let batch: Vec<_> = remaining.drain(..100.min(remaining.len())).collect();
18
- process_batch(batch);
19
- // remaining keeps its capacity - good
20
- // but batch allocates new every time - bad
21
- }
22
- }
23
-
24
- // Clears and reallocates
25
- fn reuse_buffer() {
26
- for _ in 0..1000 {
27
- let mut buffer = Vec::new(); // Allocates each iteration
28
- fill_buffer(&mut buffer);
29
- process(&buffer);
30
- }
31
- }
32
- ```
33
-
34
- ## Good
35
-
36
- ```rust
37
- // Reuses allocation with drain
38
- fn process_batches(mut data: Vec<Item>) {
39
- let mut batch = Vec::with_capacity(100);
40
-
41
- while !data.is_empty() {
42
- batch.extend(data.drain(..100.min(data.len())));
43
- process_batch(&batch);
44
- batch.clear(); // Keeps capacity
45
- }
46
- }
47
-
48
- // Reuses buffer across iterations
49
- fn reuse_buffer() {
50
- let mut buffer = Vec::new();
51
-
52
- for _ in 0..1000 {
53
- buffer.clear(); // Keeps capacity
54
- fill_buffer(&mut buffer);
55
- process(&buffer);
56
- }
57
- }
58
- ```
59
-
60
- ## Drain Methods
61
-
62
- | Collection | Method | Behavior |
63
- |------------|--------|----------|
64
- | `Vec<T>` | `.drain(range)` | Remove range, shift remaining |
65
- | `Vec<T>` | `.drain(..)` | Remove all (like clear) |
66
- | `VecDeque<T>` | `.drain(range)` | Remove range |
67
- | `String` | `.drain(range)` | Remove char range |
68
- | `HashMap<K,V>` | `.drain()` | Remove all entries |
69
- | `HashSet<T>` | `.drain()` | Remove all elements |
70
-
71
- ## Pattern: Batch Processing
72
-
73
- ```rust
74
- fn process_in_chunks(mut items: Vec<Item>, chunk_size: usize) {
75
- while !items.is_empty() {
76
- let chunk: Vec<_> = items.drain(..chunk_size.min(items.len())).collect();
77
- process_chunk(chunk);
78
- }
79
- }
80
- ```
81
-
82
- ## Pattern: Transfer Between Collections
83
-
84
- ```rust
85
- // Move all elements without reallocation
86
- fn transfer_all(src: &mut Vec<Item>, dst: &mut Vec<Item>) {
87
- dst.extend(src.drain(..));
88
- // src is now empty but keeps capacity
89
- }
90
-
91
- // Move matching elements
92
- fn transfer_matching(src: &mut Vec<Item>, dst: &mut Vec<Item>, predicate: impl Fn(&Item) -> bool) {
93
- let matching: Vec<_> = src.drain(..).filter(predicate).collect();
94
- dst.extend(matching);
95
- }
96
- ```
97
-
98
- ## Pattern: HashMap Drain
99
-
100
- ```rust
101
- use std::collections::HashMap;
102
-
103
- fn process_and_clear(map: &mut HashMap<String, Value>) {
104
- // Process all entries, clearing the map
105
- for (key, value) in map.drain() {
106
- process(key, value);
107
- }
108
- // map is now empty but keeps capacity
109
- }
110
- ```
111
-
112
- ## drain vs clear vs take
113
-
114
- | Operation | Elements | Capacity | Returns |
115
- |-----------|----------|----------|---------|
116
- | `.clear()` | Removed | Kept | Nothing |
117
- | `.drain(..)` | Removed | Kept | Iterator |
118
- | `std::mem::take()` | Moved out | Reset to 0 | Owned collection |
119
-
120
- ```rust
121
- // clear: just empty
122
- vec.clear();
123
-
124
- // drain: empty and iterate
125
- for item in vec.drain(..) {
126
- process(item);
127
- }
128
-
129
- // take: swap with empty, get ownership
130
- let old_vec = std::mem::take(&mut vec);
131
- ```
132
-
133
- ## See Also
134
-
135
- - [mem-reuse-collections](./mem-reuse-collections.md) - Reusing collections
136
- - [perf-extend-batch](./perf-extend-batch.md) - Batch insertions
137
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocation
@@ -1,134 +0,0 @@
1
- # perf-entry-api
2
-
3
- > Use entry API for map insert-or-update
4
-
5
- ## Why It Matters
6
-
7
- The entry API performs a single lookup for insert-or-update operations. Without it, you lookup twice: once to check existence, once to insert. For `HashMap` and `BTreeMap`, the entry API is both faster and more idiomatic.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use std::collections::HashMap;
13
-
14
- // Double lookup: contains_key + insert
15
- fn increment(map: &mut HashMap<String, u32>, key: String) {
16
- if map.contains_key(&key) {
17
- *map.get_mut(&key).unwrap() += 1;
18
- } else {
19
- map.insert(key, 1);
20
- }
21
- }
22
-
23
- // Double lookup with get + insert
24
- fn get_or_insert(map: &mut HashMap<String, Vec<i32>>, key: String) -> &mut Vec<i32> {
25
- if !map.contains_key(&key) {
26
- map.insert(key.clone(), Vec::new());
27
- }
28
- map.get_mut(&key).unwrap()
29
- }
30
-
31
- // Triple lookup pattern
32
- fn update_or_default(map: &mut HashMap<String, Config>, key: &str, value: i32) {
33
- match map.get(key) {
34
- Some(config) => {
35
- let mut new_config = config.clone();
36
- new_config.value = value;
37
- map.insert(key.to_string(), new_config);
38
- }
39
- None => {
40
- map.insert(key.to_string(), Config::default());
41
- }
42
- }
43
- }
44
- ```
45
-
46
- ## Good
47
-
48
- ```rust
49
- use std::collections::HashMap;
50
- use std::collections::hash_map::Entry;
51
-
52
- // Single lookup with entry
53
- fn increment(map: &mut HashMap<String, u32>, key: String) {
54
- *map.entry(key).or_insert(0) += 1;
55
- }
56
-
57
- // Single lookup, returns mutable reference
58
- fn get_or_insert(map: &mut HashMap<String, Vec<i32>>, key: String) -> &mut Vec<i32> {
59
- map.entry(key).or_insert_with(Vec::new)
60
- }
61
-
62
- // Single lookup with and_modify
63
- fn update_or_default(map: &mut HashMap<String, Config>, key: String, value: i32) {
64
- map.entry(key)
65
- .and_modify(|config| config.value = value)
66
- .or_insert_with(Config::default);
67
- }
68
- ```
69
-
70
- ## Entry API Methods
71
-
72
- | Method | Behavior |
73
- |--------|----------|
74
- | `.or_insert(val)` | Insert `val` if empty |
75
- | `.or_insert_with(f)` | Insert `f()` if empty (lazy) |
76
- | `.or_default()` | Insert `Default::default()` if empty |
77
- | `.and_modify(f)` | Apply `f` if occupied |
78
- | `.or_insert_with_key(f)` | Insert `f(&key)` if empty |
79
-
80
- ## Pattern: Count Occurrences
81
-
82
- ```rust
83
- fn word_count(text: &str) -> HashMap<&str, usize> {
84
- let mut counts = HashMap::new();
85
- for word in text.split_whitespace() {
86
- *counts.entry(word).or_insert(0) += 1;
87
- }
88
- counts
89
- }
90
- ```
91
-
92
- ## Pattern: Group By
93
-
94
- ```rust
95
- fn group_by_category(items: Vec<Item>) -> HashMap<Category, Vec<Item>> {
96
- let mut groups: HashMap<Category, Vec<Item>> = HashMap::new();
97
- for item in items {
98
- groups.entry(item.category.clone())
99
- .or_default()
100
- .push(item);
101
- }
102
- groups
103
- }
104
- ```
105
-
106
- ## Pattern: Complex Entry Logic
107
-
108
- ```rust
109
- match map.entry(key) {
110
- Entry::Occupied(mut entry) => {
111
- let value = entry.get_mut();
112
- if should_update(value) {
113
- *value = new_value;
114
- }
115
- }
116
- Entry::Vacant(entry) => {
117
- entry.insert(default_value);
118
- }
119
- }
120
- ```
121
-
122
- ## Performance
123
-
124
- | Pattern | Lookups | Hash Computations |
125
- |---------|---------|-------------------|
126
- | `contains_key` + `insert` | 2 | 2 |
127
- | `get` + `insert` | 2 | 2 |
128
- | `entry().or_insert()` | 1 | 1 |
129
-
130
- ## See Also
131
-
132
- - [perf-extend-batch](./perf-extend-batch.md) - Batch insertions
133
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocate maps
134
- - [perf-drain-reuse](./perf-drain-reuse.md) - Reuse map allocations
@@ -1,150 +0,0 @@
1
- # perf-extend-batch
2
-
3
- > Use extend for batch insertions
4
-
5
- ## Why It Matters
6
-
7
- `extend()` can pre-allocate capacity for the incoming elements and insert them in a single operation. Individual `push()` calls may trigger multiple reallocations as the collection grows. For adding multiple elements, `extend()` is both faster and clearer.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Multiple potential reallocations
13
- fn collect_results(sources: Vec<Source>) -> Vec<Result> {
14
- let mut results = Vec::new();
15
-
16
- for source in sources {
17
- for result in source.get_results() {
18
- results.push(result); // May reallocate
19
- }
20
- }
21
- results
22
- }
23
-
24
- // Loop with push for known data
25
- fn build_list() -> Vec<i32> {
26
- let mut list = Vec::new();
27
- for i in 0..1000 {
28
- list.push(i); // Many reallocations
29
- }
30
- list
31
- }
32
-
33
- // Appending another collection
34
- fn combine(mut a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
35
- for item in b {
36
- a.push(item);
37
- }
38
- a
39
- }
40
- ```
41
-
42
- ## Good
43
-
44
- ```rust
45
- // Single extend with size hint
46
- fn collect_results(sources: Vec<Source>) -> Vec<Result> {
47
- let mut results = Vec::new();
48
-
49
- for source in sources {
50
- results.extend(source.get_results());
51
- }
52
- results
53
- }
54
-
55
- // Direct collection from iterator
56
- fn build_list() -> Vec<i32> {
57
- (0..1000).collect()
58
- }
59
-
60
- // Extend for combining
61
- fn combine(mut a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
62
- a.extend(b);
63
- a
64
- }
65
- ```
66
-
67
- ## Extend with Capacity
68
-
69
- For best performance, combine with `reserve()`:
70
-
71
- ```rust
72
- fn merge_all(chunks: Vec<Vec<Item>>) -> Vec<Item> {
73
- // Calculate total size
74
- let total: usize = chunks.iter().map(|c| c.len()).sum();
75
-
76
- let mut result = Vec::with_capacity(total);
77
- for chunk in chunks {
78
- result.extend(chunk);
79
- }
80
- result
81
- }
82
- ```
83
-
84
- ## Extend Methods
85
-
86
- | Method | Description |
87
- |--------|-------------|
88
- | `.extend(iter)` | Add all elements from iterator |
89
- | `.extend_from_slice(&[T])` | Add from slice (for `Copy` types) |
90
- | `.append(&mut Vec)` | Move all from another Vec |
91
-
92
- ## Pattern: Building Strings
93
-
94
- ```rust
95
- // Bad: multiple allocations
96
- fn build_message(parts: &[&str]) -> String {
97
- let mut result = String::new();
98
- for part in parts {
99
- result.push_str(part); // May reallocate
100
- }
101
- result
102
- }
103
-
104
- // Good: extend with known parts
105
- fn build_message(parts: &[&str]) -> String {
106
- let total_len: usize = parts.iter().map(|s| s.len()).sum();
107
- let mut result = String::with_capacity(total_len);
108
- for part in parts {
109
- result.push_str(part);
110
- }
111
- result
112
- }
113
-
114
- // Better: collect/join
115
- fn build_message(parts: &[&str]) -> String {
116
- parts.concat() // or parts.join("")
117
- }
118
- ```
119
-
120
- ## HashMap/HashSet Extend
121
-
122
- ```rust
123
- use std::collections::HashMap;
124
-
125
- // Extend from iterator of tuples
126
- fn merge_maps(mut base: HashMap<String, i32>, other: HashMap<String, i32>) -> HashMap<String, i32> {
127
- base.extend(other); // Moves entries from other
128
- base
129
- }
130
-
131
- // Extend from iterator
132
- let mut set = HashSet::new();
133
- set.extend(items.iter().map(|i| i.id));
134
- ```
135
-
136
- ## Performance
137
-
138
- | Operation | Allocations | Complexity |
139
- |-----------|-------------|------------|
140
- | N × `push()` | O(log N) | O(N) amortized |
141
- | `extend(iter)` | O(1)* | O(N) |
142
- | `with_capacity` + `extend` | 1 | O(N) |
143
-
144
- *When iterator provides accurate `size_hint()`
145
-
146
- ## See Also
147
-
148
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocation
149
- - [perf-drain-reuse](./perf-drain-reuse.md) - Reusing allocations
150
- - [mem-reuse-collections](./mem-reuse-collections.md) - Collection reuse