agy-superpowers 5.2.2 → 5.2.4

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 (231) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/CLAUDE.md +80 -0
  4. package/template/agent/rules/code-styles.md +31 -32
  5. package/template/agent/rules/debug-confirmation-policy.md +2 -0
  6. package/template/agent/rules/file-length-policy.md +2 -0
  7. package/template/agent/rules/git-policy.md +7 -0
  8. package/template/agent/rules/language-matching.md +2 -0
  9. package/template/agent/rules/scratch-scripts.md +39 -0
  10. package/template/agent/rules/superpowers.md +8 -51
  11. package/template/agent/skills/executing-plans/SKILL.md +17 -0
  12. package/template/agent/skills/systematic-debugging/SKILL.md +16 -0
  13. package/template/agent/skills/test-driven-development/SKILL.md +16 -0
  14. package/template/agent/skills/verification-before-completion/SKILL.md +22 -0
  15. package/template/agent/skills/writing-plans/SKILL.md +16 -0
  16. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  17. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  18. package/template/agent/skills/api-design/SKILL.md +0 -193
  19. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  20. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  21. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  22. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  23. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  24. package/template/agent/skills/community-manager/SKILL.md +0 -115
  25. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  26. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  27. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  28. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  29. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  30. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  31. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  32. package/template/agent/skills/game-design/SKILL.md +0 -194
  33. package/template/agent/skills/game-developer/SKILL.md +0 -175
  34. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  35. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  36. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  37. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  38. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  39. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  40. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  41. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  42. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  43. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  44. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  45. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  46. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  47. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  48. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  94. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  95. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  106. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  117. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  118. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  160. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  172. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  183. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  184. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  194. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  195. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  218. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  228. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  229. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  230. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  231. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,168 +0,0 @@
1
- # mem-arena-allocator
2
-
3
- > Use arena allocators for batch allocations
4
-
5
- ## Why It Matters
6
-
7
- Arena allocators (bump allocators) allocate memory from a contiguous region, making allocation extremely fast (just bump a pointer). All allocations are freed at once when the arena is dropped. Perfect for request-scoped or parse-tree allocations.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Many small allocations during parsing
13
- fn parse(input: &str) -> Vec<Node> {
14
- let mut nodes = Vec::new();
15
- for token in tokenize(input) {
16
- nodes.push(Box::new(Node::new(token))); // Heap alloc per node!
17
- }
18
- nodes
19
- }
20
-
21
- // Per-request allocations add up
22
- fn handle_request(req: Request) -> Response {
23
- let headers = parse_headers(&req); // Allocates
24
- let body = parse_body(&req); // Allocates
25
- let response = generate_response(); // Allocates
26
- // All freed individually at end
27
- response
28
- }
29
- ```
30
-
31
- ## Good
32
-
33
- ```rust
34
- use bumpalo::Bump;
35
-
36
- // All nodes allocated from same arena
37
- fn parse<'a>(input: &str, arena: &'a Bump) -> Vec<&'a Node> {
38
- let mut nodes = Vec::new();
39
- for token in tokenize(input) {
40
- let node = arena.alloc(Node::new(token)); // Fast bump!
41
- nodes.push(node);
42
- }
43
- nodes
44
- } // Arena freed all at once
45
-
46
- // Per-request arena
47
- fn handle_request(req: Request) -> Response {
48
- let arena = Bump::new();
49
-
50
- let headers = parse_headers(&req, &arena);
51
- let body = parse_body(&req, &arena);
52
- let response = generate_response(&arena);
53
-
54
- // Convert to owned response before arena drops
55
- response.to_owned()
56
- } // All request memory freed instantly
57
- ```
58
-
59
- ## Thread-Local Scratch Arena Pattern
60
-
61
- ```rust
62
- use bumpalo::Bump;
63
- use std::cell::RefCell;
64
-
65
- thread_local! {
66
- static SCRATCH: RefCell<Bump> = RefCell::new(Bump::with_capacity(4 * 1024));
67
- }
68
-
69
- fn with_scratch<T>(f: impl FnOnce(&Bump) -> T) -> T {
70
- SCRATCH.with(|scratch| {
71
- let arena = scratch.borrow();
72
- let result = f(&arena);
73
- result
74
- })
75
- }
76
-
77
- fn reset_scratch() {
78
- SCRATCH.with(|scratch| {
79
- scratch.borrow_mut().reset();
80
- });
81
- }
82
-
83
- // Usage
84
- fn process_batch(items: &[Item]) -> Vec<Output> {
85
- with_scratch(|arena| {
86
- let temp_data: Vec<&TempData> = items
87
- .iter()
88
- .map(|item| arena.alloc(compute_temp(item)))
89
- .collect();
90
-
91
- // Use temp_data...
92
- let result = finalize(&temp_data);
93
-
94
- reset_scratch(); // Reuse arena memory
95
- result
96
- })
97
- }
98
- ```
99
-
100
- ## Evidence from ROC Compiler
101
-
102
- ```rust
103
- // https://github.com/roc-lang/roc/blob/main/crates/compiler/solve/src/to_var.rs
104
- std::thread_local! {
105
- static SCRATCHPAD: RefCell<Option<bumpalo::Bump>> =
106
- RefCell::new(Some(bumpalo::Bump::with_capacity(4 * 1024)));
107
- }
108
-
109
- fn take_scratchpad() -> bumpalo::Bump {
110
- SCRATCHPAD.with(|f| f.take().unwrap())
111
- }
112
-
113
- fn put_scratchpad(scratchpad: bumpalo::Bump) {
114
- SCRATCHPAD.with(|f| {
115
- f.replace(Some(scratchpad));
116
- });
117
- }
118
- ```
119
-
120
- ## Bumpalo Collections
121
-
122
- ```rust
123
- use bumpalo::Bump;
124
- use bumpalo::collections::{Vec, String};
125
-
126
- fn process<'a>(arena: &'a Bump, input: &str) -> Vec<'a, String<'a>> {
127
- let mut results = Vec::new_in(arena);
128
-
129
- for word in input.split_whitespace() {
130
- let mut s = String::new_in(arena);
131
- s.push_str(word);
132
- s.push_str("_processed");
133
- results.push(s);
134
- }
135
-
136
- results // All allocated in arena
137
- }
138
- ```
139
-
140
- ## When to Use Arenas
141
-
142
- | Situation | Use Arena? |
143
- |-----------|-----------|
144
- | Parsing (AST nodes) | Yes |
145
- | Request handling | Yes |
146
- | Batch processing | Yes |
147
- | Long-lived data | No |
148
- | Data escaping scope | No (or copy out) |
149
- | Simple programs | Overkill |
150
-
151
- ## Performance Impact
152
-
153
- ```rust
154
- // Benchmarks from production systems:
155
- // - Individual allocations: ~25-50ns each
156
- // - Arena bump: ~1-2ns each (20-50x faster)
157
- // - Arena reset: O(1) regardless of allocation count
158
-
159
- // Memory overhead:
160
- // - Arena wastes some memory (unused capacity)
161
- // - But eliminates per-allocation metadata overhead
162
- ```
163
-
164
- ## See Also
165
-
166
- - [mem-with-capacity](mem-with-capacity.md) - Pre-allocate when size is known
167
- - [mem-reuse-collections](mem-reuse-collections.md) - Reuse collections with clear()
168
- - [opt-profile-first](perf-profile-first.md) - Profile to verify benefit
@@ -1,142 +0,0 @@
1
- # mem-arrayvec
2
-
3
- > Use `ArrayVec<T, N>` for fixed-capacity collections that never heap-allocate
4
-
5
- ## Why It Matters
6
-
7
- `ArrayVec` from the `arrayvec` crate provides Vec-like API with a compile-time maximum capacity, storing all elements inline on the stack. Unlike `SmallVec` which can spill to heap, `ArrayVec` guarantees no heap allocation—if you exceed capacity, it returns an error or panics. This is ideal for embedded systems, real-time code, or when you have a hard upper bound.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Vec always heap-allocates, even for small collections
13
- fn parse_options(input: &str) -> Vec<Option> {
14
- let mut options = Vec::new(); // Heap allocation
15
- for part in input.split(',').take(8) { // Know we never exceed 8
16
- options.push(parse_option(part));
17
- }
18
- options
19
- }
20
-
21
- // Or SmallVec when you truly can't exceed capacity
22
- use smallvec::SmallVec;
23
- fn get_flags() -> SmallVec<[Flag; 4]> {
24
- // SmallVec CAN heap-allocate if pushed beyond 4
25
- // That might be unexpected in no-alloc contexts
26
- }
27
- ```
28
-
29
- ## Good
30
-
31
- ```rust
32
- use arrayvec::ArrayVec;
33
-
34
- // Guaranteed no heap allocation
35
- fn parse_options(input: &str) -> ArrayVec<Option, 8> {
36
- let mut options = ArrayVec::new();
37
- for part in input.split(',') {
38
- if options.try_push(parse_option(part)).is_err() {
39
- break; // Capacity reached, stop
40
- }
41
- }
42
- options
43
- }
44
-
45
- // For embedded/no_std contexts
46
- #[no_std]
47
- fn collect_readings() -> ArrayVec<SensorReading, 16> {
48
- let mut readings = ArrayVec::new();
49
- for sensor in SENSORS.iter() {
50
- readings.push(sensor.read()); // Panics if > 16
51
- }
52
- readings
53
- }
54
- ```
55
-
56
- ## ArrayVec vs SmallVec vs Vec
57
-
58
- | Type | Stack | Heap | Use When |
59
- |------|-------|------|----------|
60
- | `Vec<T>` | Never | Always | Unknown size, may grow indefinitely |
61
- | `SmallVec<[T; N]>` | Up to N | Beyond N | Usually small, occasionally large |
62
- | `ArrayVec<T, N>` | Always | Never | Hard limit, no heap allowed |
63
-
64
- ## API Patterns
65
-
66
- ```rust
67
- use arrayvec::ArrayVec;
68
-
69
- let mut arr: ArrayVec<i32, 4> = ArrayVec::new();
70
-
71
- // Push with potential panic (like Vec)
72
- arr.push(1);
73
- arr.push(2);
74
-
75
- // Safe push - returns Err if full
76
- match arr.try_push(3) {
77
- Ok(()) => println!("Added"),
78
- Err(err) => println!("Full, couldn't add {}", err.element()),
79
- }
80
-
81
- // Check capacity
82
- assert!(arr.len() < arr.capacity());
83
-
84
- // Remaining capacity
85
- let remaining = arr.remaining_capacity();
86
-
87
- // Is it full?
88
- if arr.is_full() {
89
- arr.pop();
90
- }
91
-
92
- // From iterator with limit
93
- let arr: ArrayVec<_, 10> = (0..100)
94
- .filter(|x| x % 2 == 0)
95
- .take(10) // Important: don't exceed capacity
96
- .collect();
97
- ```
98
-
99
- ## ArrayString for Stack Strings
100
-
101
- ```rust
102
- use arrayvec::ArrayString;
103
-
104
- // Stack-allocated string with max capacity
105
- let mut s: ArrayString<64> = ArrayString::new();
106
- s.push_str("Hello, ");
107
- s.push_str("world!");
108
-
109
- // No heap allocation for small strings
110
- fn format_code(code: u32) -> ArrayString<16> {
111
- let mut s = ArrayString::new();
112
- write!(&mut s, "CODE-{:04}", code).unwrap();
113
- s
114
- }
115
- ```
116
-
117
- ## When NOT to Use ArrayVec
118
-
119
- ```rust
120
- // ❌ When size varies widely
121
- fn parse_json_array(json: &str) -> ArrayVec<Value, ???> {
122
- // What capacity? JSON arrays can be any size
123
- }
124
-
125
- // ❌ When capacity is very large
126
- let big: ArrayVec<u8, 1_000_000> = ArrayVec::new(); // 1MB on stack = bad
127
-
128
- // ✅ Use SmallVec or Vec instead for these cases
129
- ```
130
-
131
- ## Cargo.toml
132
-
133
- ```toml
134
- [dependencies]
135
- arrayvec = "0.7"
136
- ```
137
-
138
- ## See Also
139
-
140
- - [mem-smallvec](./mem-smallvec.md) - When heap fallback is acceptable
141
- - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating Vec capacity
142
- - [own-move-large](./own-move-large.md) - Large stack types considerations
@@ -1,168 +0,0 @@
1
- # mem-assert-type-size
2
-
3
- > Use static assertions to guard against accidental type size growth
4
-
5
- ## Why It Matters
6
-
7
- Adding a field to a frequently-instantiated struct can silently bloat memory usage. Static size assertions catch this at compile time, making size changes intentional rather than accidental. This is especially important for types stored in large collections or passed frequently by value.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Event {
13
- timestamp: u64,
14
- kind: EventKind,
15
- payload: [u8; 32],
16
- }
17
-
18
- // Later, someone adds a field without realizing the impact
19
- struct Event {
20
- timestamp: u64,
21
- kind: EventKind,
22
- payload: [u8; 32],
23
- metadata: String, // Silently adds 24 bytes!
24
- }
25
-
26
- // 10 million events now use 240MB more memory
27
- // No warning, no review trigger
28
- ```
29
-
30
- ## Good
31
-
32
- ```rust
33
- struct Event {
34
- timestamp: u64,
35
- kind: EventKind,
36
- payload: [u8; 32],
37
- }
38
-
39
- // Static assertion - breaks compile if size changes
40
- const _: () = assert!(std::mem::size_of::<Event>() == 48);
41
-
42
- // Or with static_assertions crate
43
- use static_assertions::assert_eq_size;
44
- assert_eq_size!(Event, [u8; 48]);
45
-
46
- // Now adding metadata triggers compile error:
47
- // error: assertion failed: std::mem::size_of::<Event>() == 48
48
- ```
49
-
50
- ## static_assertions Crate
51
-
52
- ```rust
53
- use static_assertions::{assert_eq_size, const_assert};
54
-
55
- struct Critical {
56
- id: u64,
57
- flags: u32,
58
- data: [u8; 16],
59
- }
60
-
61
- // Exact size assertion
62
- assert_eq_size!(Critical, [u8; 32]);
63
-
64
- // Maximum size assertion
65
- const_assert!(std::mem::size_of::<Critical>() <= 64);
66
-
67
- // Alignment assertion
68
- const_assert!(std::mem::align_of::<Critical>() == 8);
69
-
70
- // Compare sizes
71
- assert_eq_size!(Critical, [u64; 4]);
72
- ```
73
-
74
- ## Built-in Const Assertions
75
-
76
- ```rust
77
- // No external crate needed (Rust 1.57+)
78
- struct Packet {
79
- header: u32,
80
- payload: [u8; 60],
81
- }
82
-
83
- const _: () = assert!(
84
- std::mem::size_of::<Packet>() == 64,
85
- "Packet must be exactly 64 bytes for protocol compliance"
86
- );
87
-
88
- // Compile error shows custom message if assertion fails
89
- ```
90
-
91
- ## Documenting Size Constraints
92
-
93
- ```rust
94
- /// Network protocol packet header.
95
- ///
96
- /// # Size
97
- ///
98
- /// This struct is guaranteed to be exactly 32 bytes to match
99
- /// the network protocol specification. Any changes to fields
100
- /// must maintain this size constraint.
101
- #[repr(C)] // Predictable layout for FFI
102
- struct Header {
103
- version: u16,
104
- flags: u16,
105
- length: u32,
106
- checksum: u64,
107
- reserved: [u8; 16],
108
- }
109
-
110
- const _: () = assert!(std::mem::size_of::<Header>() == 32);
111
- ```
112
-
113
- ## Testing Size Stability
114
-
115
- ```rust
116
- #[cfg(test)]
117
- mod tests {
118
- use super::*;
119
-
120
- #[test]
121
- fn critical_types_have_expected_sizes() {
122
- // Document expected sizes in tests too
123
- assert_eq!(std::mem::size_of::<Event>(), 48);
124
- assert_eq!(std::mem::size_of::<Message>(), 64);
125
- assert_eq!(std::mem::size_of::<Header>(), 32);
126
- }
127
-
128
- #[test]
129
- fn cache_line_aligned() {
130
- // Verify cache-friendly sizing
131
- assert!(std::mem::size_of::<HotData>() <= 64);
132
- }
133
- }
134
- ```
135
-
136
- ## When to Assert
137
-
138
- ```rust
139
- // ✅ Types stored in large collections
140
- struct Node { /* ... */ }
141
- const _: () = assert!(std::mem::size_of::<Node>() <= 64);
142
-
143
- // ✅ Types used in FFI / binary protocols
144
- #[repr(C)]
145
- struct WireFormat { /* ... */ }
146
- const _: () = assert!(std::mem::size_of::<WireFormat>() == 256);
147
-
148
- // ✅ Performance-critical types
149
- struct HotPath { /* ... */ }
150
- const _: () = assert!(std::mem::size_of::<HotPath>() <= 128);
151
-
152
- // ❌ Skip for rarely-instantiated types
153
- struct AppConfig { /* many fields */ }
154
- // Size doesn't matter, only one instance
155
- ```
156
-
157
- ## Cargo.toml
158
-
159
- ```toml
160
- [dependencies]
161
- static_assertions = "1.1"
162
- ```
163
-
164
- ## See Also
165
-
166
- - [mem-smaller-integers](./mem-smaller-integers.md) - Choosing appropriate integer sizes
167
- - [mem-box-large-variant](./mem-box-large-variant.md) - Managing enum variant sizes
168
- - [opt-cache-friendly](./opt-cache-friendly.md) - Cache line considerations
@@ -1,147 +0,0 @@
1
- # mem-avoid-format
2
-
3
- > Avoid `format!()` when string literals work
4
-
5
- ## Why It Matters
6
-
7
- `format!()` always allocates a new String, even for constant text. In hot paths, these allocations add up. Use string literals, `write!()`, or pre-allocated buffers instead.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Allocates every time, even for static text
13
- fn get_error_message() -> String {
14
- format!("An error occurred") // Unnecessary allocation!
15
- }
16
-
17
- // Allocates in a loop
18
- for item in items {
19
- log::info!("{}", format!("Processing item: {}", item)); // Double work!
20
- }
21
-
22
- // format! in hot path
23
- fn classify(n: i32) -> String {
24
- if n > 0 {
25
- format!("positive") // Allocates!
26
- } else if n < 0 {
27
- format!("negative") // Allocates!
28
- } else {
29
- format!("zero") // Allocates!
30
- }
31
- }
32
- ```
33
-
34
- ## Good
35
-
36
- ```rust
37
- // Return &'static str for constants
38
- fn get_error_message() -> &'static str {
39
- "An error occurred" // No allocation
40
- }
41
-
42
- // Use format args directly
43
- for item in items {
44
- log::info!("Processing item: {}", item); // No intermediate String
45
- }
46
-
47
- // Return Cow for mixed static/dynamic
48
- use std::borrow::Cow;
49
-
50
- fn classify(n: i32) -> Cow<'static, str> {
51
- if n > 0 {
52
- Cow::Borrowed("positive") // No allocation
53
- } else if n < 0 {
54
- Cow::Borrowed("negative") // No allocation
55
- } else {
56
- Cow::Borrowed("zero") // No allocation
57
- }
58
- }
59
-
60
- // Or just &'static str if always static
61
- fn classify_str(n: i32) -> &'static str {
62
- if n > 0 { "positive" }
63
- else if n < 0 { "negative" }
64
- else { "zero" }
65
- }
66
- ```
67
-
68
- ## Use write!() for Output
69
-
70
- ```rust
71
- use std::io::Write;
72
-
73
- // Bad: Allocate then write
74
- fn bad_log(writer: &mut impl Write, msg: &str, code: u32) {
75
- let formatted = format!("[ERROR {}] {}", code, msg); // Allocation!
76
- writer.write_all(formatted.as_bytes()).unwrap();
77
- }
78
-
79
- // Good: Write directly
80
- fn good_log(writer: &mut impl Write, msg: &str, code: u32) {
81
- write!(writer, "[ERROR {}] {}", code, msg).unwrap(); // No allocation!
82
- }
83
- ```
84
-
85
- ## Pre-allocate for Multiple Appends
86
-
87
- ```rust
88
- // Bad: Multiple allocations
89
- fn build_message(parts: &[&str]) -> String {
90
- let mut result = String::new();
91
- for part in parts {
92
- result = format!("{}{}\n", result, part); // Allocates each iteration!
93
- }
94
- result
95
- }
96
-
97
- // Good: Pre-allocate
98
- fn build_message(parts: &[&str]) -> String {
99
- let total_len: usize = parts.iter().map(|p| p.len() + 1).sum();
100
- let mut result = String::with_capacity(total_len);
101
- for part in parts {
102
- result.push_str(part);
103
- result.push('\n');
104
- }
105
- result
106
- }
107
-
108
- // Good: Use join
109
- fn build_message(parts: &[&str]) -> String {
110
- parts.join("\n")
111
- }
112
- ```
113
-
114
- ## CompactString for Small Strings
115
-
116
- ```rust
117
- use compact_str::CompactString;
118
-
119
- // Stack-allocated for strings <= 24 bytes
120
- fn format_code(code: u32) -> CompactString {
121
- compact_str::format_compact!("ERR-{:04}", code)
122
- // Stack-allocated if result is small enough
123
- }
124
- ```
125
-
126
- ## When format!() Is Fine
127
-
128
- ```rust
129
- // Rare/cold paths - clarity over micro-optimization
130
- fn log_startup_message() {
131
- println!("{}", format!("Starting {} v{}", APP_NAME, VERSION));
132
- }
133
-
134
- // When you need an owned String anyway
135
- fn create_user_greeting(name: &str) -> String {
136
- format!("Hello, {}!", name) // Need owned String
137
- }
138
-
139
- // Error messages (already on error path)
140
- return Err(format!("Invalid value: {}", value).into());
141
- ```
142
-
143
- ## See Also
144
-
145
- - [mem-write-over-format](mem-write-over-format.md) - Use write!() instead of format!()
146
- - [mem-with-capacity](mem-with-capacity.md) - Pre-allocate strings
147
- - [own-cow-conditional](own-cow-conditional.md) - Use Cow for mixed static/dynamic