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,97 +0,0 @@
1
- # own-refcell-interior
2
-
3
- > Use `RefCell<T>` for interior mutability in single-threaded code
4
-
5
- ## Why It Matters
6
-
7
- Rust's borrow checker enforces rules at compile time, but sometimes you need to mutate data through a shared reference. `RefCell<T>` moves borrow checking to runtime, allowing mutation through `&self`. This is essential for patterns like caches, lazy initialization, and observer patterns where compile-time borrowing is too restrictive.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Cache {
13
- // Requires &mut self to update, breaking shared reference patterns
14
- data: HashMap<String, String>,
15
- }
16
-
17
- impl Cache {
18
- fn get_or_compute(&mut self, key: &str) -> &str {
19
- // Caller needs &mut Cache, can't share cache reference
20
- if !self.data.contains_key(key) {
21
- self.data.insert(key.to_string(), expensive_compute(key));
22
- }
23
- &self.data[key]
24
- }
25
- }
26
- ```
27
-
28
- This forces exclusive access even for logically shared operations.
29
-
30
- ## Good
31
-
32
- ```rust
33
- use std::cell::RefCell;
34
- use std::collections::HashMap;
35
-
36
- struct Cache {
37
- data: RefCell<HashMap<String, String>>,
38
- }
39
-
40
- impl Cache {
41
- fn get_or_compute(&self, key: &str) -> String {
42
- // Can mutate through &self
43
- let mut data = self.data.borrow_mut();
44
- if !data.contains_key(key) {
45
- data.insert(key.to_string(), expensive_compute(key));
46
- }
47
- data[key].clone()
48
- }
49
- }
50
-
51
- // Multiple references can coexist
52
- let cache = Cache::new();
53
- let ref1 = &cache;
54
- let ref2 = &cache;
55
- ref1.get_or_compute("key1");
56
- ref2.get_or_compute("key2");
57
- ```
58
-
59
- ## Common Pattern: Rc<RefCell<T>>
60
-
61
- ```rust
62
- use std::rc::Rc;
63
- use std::cell::RefCell;
64
-
65
- // Shared mutable state in single-threaded code
66
- type SharedState = Rc<RefCell<AppState>>;
67
-
68
- fn create_handlers(state: SharedState) -> Vec<Box<dyn Fn()>> {
69
- vec![
70
- Box::new({
71
- let state = state.clone();
72
- move || state.borrow_mut().increment()
73
- }),
74
- Box::new({
75
- let state = state.clone();
76
- move || state.borrow_mut().decrement()
77
- }),
78
- ]
79
- }
80
- ```
81
-
82
- ## Runtime Panics
83
-
84
- `RefCell` panics if you violate borrowing rules at runtime:
85
-
86
- ```rust
87
- let cell = RefCell::new(5);
88
- let borrow1 = cell.borrow();
89
- let borrow2 = cell.borrow_mut(); // PANIC: already borrowed
90
- ```
91
-
92
- Use `try_borrow()` and `try_borrow_mut()` for fallible borrowing.
93
-
94
- ## See Also
95
-
96
- - [own-rc-single-thread](./own-rc-single-thread.md) - Combining with Rc for shared ownership
97
- - [own-mutex-interior](./own-mutex-interior.md) - Thread-safe alternative
@@ -1,122 +0,0 @@
1
- # own-rwlock-readers
2
-
3
- > Use `RwLock<T>` when reads significantly outnumber writes
4
-
5
- ## Why It Matters
6
-
7
- `Mutex<T>` allows only one thread to access data at a time, even for reads. `RwLock<T>` allows multiple concurrent readers OR one exclusive writer. For read-heavy workloads, this dramatically improves throughput by eliminating unnecessary serialization of read operations.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use std::sync::{Arc, Mutex};
13
-
14
- // Configuration rarely changes but is read constantly
15
- let config = Arc::new(Mutex::new(Config::load()));
16
-
17
- // Every read blocks other reads unnecessarily
18
- fn get_setting(config: &Mutex<Config>, key: &str) -> String {
19
- let guard = config.lock().unwrap();
20
- guard.get(key).to_string()
21
- }
22
-
23
- // 100 threads reading = serialized, one at a time
24
- ```
25
-
26
- ## Good
27
-
28
- ```rust
29
- use std::sync::{Arc, RwLock};
30
-
31
- // Multiple readers can proceed concurrently
32
- let config = Arc::new(RwLock::new(Config::load()));
33
-
34
- fn get_setting(config: &RwLock<Config>, key: &str) -> String {
35
- let guard = config.read().unwrap(); // Multiple threads can hold read lock
36
- guard.get(key).to_string()
37
- }
38
-
39
- fn update_setting(config: &RwLock<Config>, key: &str, value: &str) {
40
- let mut guard = config.write().unwrap(); // Exclusive access for writes
41
- guard.set(key, value);
42
- }
43
-
44
- // 100 threads reading = parallel execution
45
- ```
46
-
47
- ## parking_lot::RwLock
48
-
49
- Prefer `parking_lot::RwLock` for better performance:
50
-
51
- ```rust
52
- use parking_lot::RwLock;
53
- use std::sync::Arc;
54
-
55
- let data = Arc::new(RwLock::new(HashMap::new()));
56
-
57
- // Read - no unwrap needed
58
- let value = data.read().get("key").cloned();
59
-
60
- // Write
61
- data.write().insert("key".to_string(), "value".to_string());
62
-
63
- // Upgradeable read lock (unique to parking_lot)
64
- let upgradeable = data.upgradable_read();
65
- if upgradeable.get("key").is_none() {
66
- let mut write = parking_lot::RwLockUpgradableReadGuard::upgrade(upgradeable);
67
- write.insert("key".to_string(), "default".to_string());
68
- }
69
- ```
70
-
71
- ## When RwLock Hurts
72
-
73
- RwLock has overhead for tracking readers. It can be slower than Mutex when:
74
-
75
- | Scenario | Better Choice |
76
- |----------|---------------|
77
- | Writes are frequent (>20% of operations) | `Mutex` |
78
- | Lock held very briefly | `Mutex` |
79
- | Single-threaded | `RefCell` |
80
- | Reads dominate, lock held longer | `RwLock` |
81
-
82
- ## Write Starvation
83
-
84
- Standard `RwLock` may starve writers if readers are continuous. `parking_lot::RwLock` is fair by default.
85
-
86
- ```rust
87
- // parking_lot is writer-fair, preventing starvation
88
- use parking_lot::RwLock;
89
-
90
- // Or use std with explicit fairness (nightly)
91
- // #![feature(rwlock_downgrade)]
92
- ```
93
-
94
- ## Real-World Pattern: Cached Computation
95
-
96
- ```rust
97
- use parking_lot::RwLock;
98
- use std::sync::Arc;
99
-
100
- struct CachedData {
101
- cache: RwLock<Option<ExpensiveResult>>,
102
- }
103
-
104
- impl CachedData {
105
- fn get(&self) -> ExpensiveResult {
106
- // Fast path: read lock
107
- if let Some(cached) = self.cache.read().as_ref() {
108
- return cached.clone();
109
- }
110
-
111
- // Slow path: compute and cache
112
- let result = compute_expensive();
113
- *self.cache.write() = Some(result.clone());
114
- result
115
- }
116
- }
117
- ```
118
-
119
- ## See Also
120
-
121
- - [own-mutex-interior](./own-mutex-interior.md) - When writes are frequent
122
- - [async-no-lock-await](./async-no-lock-await.md) - RwLock in async contexts
@@ -1,119 +0,0 @@
1
- # own-slice-over-vec
2
-
3
- > Accept `&[T]` not `&Vec<T>`, `&str` not `&String`
4
-
5
- ## Why It Matters
6
-
7
- Accepting `&[T]` instead of `&Vec<T>` makes your function more flexible - it can accept slices from arrays, vectors, or other sources. Similarly, `&str` accepts string slices from `String`, `&'static str`, or substrings.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Overly restrictive - only accepts &Vec
13
- fn sum(numbers: &Vec<i32>) -> i32 {
14
- numbers.iter().sum()
15
- }
16
-
17
- // Overly restrictive - only accepts &String
18
- fn greet(name: &String) {
19
- println!("Hello, {}", name);
20
- }
21
-
22
- // Can't call with arrays or slices
23
- let arr = [1, 2, 3];
24
- // sum(&arr); // ERROR: expected &Vec<i32>
25
-
26
- let literal = "world";
27
- // greet(&literal); // ERROR: expected &String
28
- ```
29
-
30
- ## Good
31
-
32
- ```rust
33
- // Flexible - accepts any slice-like thing
34
- fn sum(numbers: &[i32]) -> i32 {
35
- numbers.iter().sum()
36
- }
37
-
38
- // Flexible - accepts any string-like thing
39
- fn greet(name: &str) {
40
- println!("Hello, {}", name);
41
- }
42
-
43
- // Now all of these work:
44
- let vec = vec![1, 2, 3];
45
- let arr = [4, 5, 6];
46
- let slice = &vec[0..2];
47
-
48
- sum(&vec); // Vec coerces to slice
49
- sum(&arr); // Array coerces to slice
50
- sum(slice); // Slice works directly
51
-
52
- let string = String::from("Alice");
53
- let literal = "Bob";
54
-
55
- greet(&string); // String coerces to &str
56
- greet(literal); // &str works directly
57
- ```
58
-
59
- ## The Deref Coercion Chain
60
-
61
- ```rust
62
- // These coercions happen automatically:
63
- // Vec<T> -> &[T] (via Deref)
64
- // String -> &str (via Deref)
65
- // Box<T> -> &T (via Deref)
66
- // Arc<T> -> &T (via Deref)
67
-
68
- fn process(data: &[u8]) { /* ... */ }
69
-
70
- let vec: Vec<u8> = vec![1, 2, 3];
71
- let boxed: Box<[u8]> = vec.into_boxed_slice();
72
- let arc: Arc<[u8]> = Arc::from(&[1, 2, 3][..]);
73
-
74
- process(&vec); // Works
75
- process(&boxed); // Works
76
- process(&arc); // Works
77
- ```
78
-
79
- ## Path Types Too
80
-
81
- ```rust
82
- // Bad
83
- fn read_config(path: &PathBuf) -> Config { /* ... */ }
84
-
85
- // Good - accepts &Path, &PathBuf, &str, &String
86
- fn read_config(path: &Path) -> Config { /* ... */ }
87
-
88
- // Even better - accept anything path-like
89
- fn read_config(path: impl AsRef<Path>) -> Config {
90
- let path = path.as_ref();
91
- // ...
92
- }
93
- ```
94
-
95
- ## When to Accept Owned Types
96
-
97
- ```rust
98
- // Accept owned when you need to store it
99
- struct Logger {
100
- prefix: String, // Needs to own the string
101
- }
102
-
103
- impl Logger {
104
- // Take ownership - caller decides to clone or move
105
- fn new(prefix: String) -> Self {
106
- Self { prefix }
107
- }
108
-
109
- // Or use Into for flexibility
110
- fn with_prefix(prefix: impl Into<String>) -> Self {
111
- Self { prefix: prefix.into() }
112
- }
113
- }
114
- ```
115
-
116
- ## See Also
117
-
118
- - [api-impl-asref](api-impl-asref.md) - Accept `impl AsRef<T>` for maximum flexibility
119
- - [own-borrow-over-clone](own-borrow-over-clone.md) - Prefer borrowing over cloning
@@ -1,153 +0,0 @@
1
- # perf-black-box-bench
2
-
3
- > Use black_box in benchmarks
4
-
5
- ## Why It Matters
6
-
7
- The compiler aggressively optimizes code, potentially eliminating computations whose results aren't used. In benchmarks, this can lead to measuring nothing instead of the actual code. `std::hint::black_box()` prevents the compiler from optimizing away values, ensuring accurate measurements.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use criterion::{black_box, criterion_group, criterion_main, Criterion};
13
-
14
- fn benchmark_bad(c: &mut Criterion) {
15
- c.bench_function("compute", |b| {
16
- b.iter(|| {
17
- let result = expensive_computation(42);
18
- // Result unused - compiler may eliminate the call!
19
- });
20
- });
21
- }
22
-
23
- fn benchmark_also_bad(c: &mut Criterion) {
24
- let input = 42; // Constant - compiler may precompute
25
-
26
- c.bench_function("compute", |b| {
27
- b.iter(|| {
28
- expensive_computation(input)
29
- // Return value may still be optimized away
30
- });
31
- });
32
- }
33
- ```
34
-
35
- ## Good
36
-
37
- ```rust
38
- use criterion::{black_box, criterion_group, criterion_main, Criterion};
39
-
40
- fn benchmark_good(c: &mut Criterion) {
41
- c.bench_function("compute", |b| {
42
- b.iter(|| {
43
- // black_box on input prevents constant folding
44
- let result = expensive_computation(black_box(42));
45
- // black_box on output prevents dead code elimination
46
- black_box(result)
47
- });
48
- });
49
- }
50
-
51
- // Or simpler with Criterion's built-in support
52
- fn benchmark_simpler(c: &mut Criterion) {
53
- c.bench_function("compute", |b| {
54
- b.iter(|| expensive_computation(black_box(42)))
55
- });
56
- }
57
- ```
58
-
59
- ## What black_box Does
60
-
61
- | Without black_box | With black_box |
62
- |-------------------|----------------|
63
- | Input may be constant-folded | Input treated as unknown |
64
- | Result may be eliminated | Result must be computed |
65
- | Loops may be optimized away | Each iteration runs |
66
- | Functions may be inlined | Call semantics preserved |
67
-
68
- ## Standard Library Usage
69
-
70
- ```rust
71
- use std::hint::black_box;
72
-
73
- fn main() {
74
- // In std since Rust 1.66
75
- let result = black_box(compute_something(black_box(input)));
76
- }
77
- ```
78
-
79
- ## Criterion's black_box
80
-
81
- Criterion re-exports `std::hint::black_box`:
82
-
83
- ```rust
84
- use criterion::black_box;
85
-
86
- // Equivalent to std::hint::black_box
87
- ```
88
-
89
- ## Pattern: Benchmark with Setup
90
-
91
- ```rust
92
- fn benchmark_with_setup(c: &mut Criterion) {
93
- c.bench_function("process_data", |b| {
94
- // Setup outside iter - not measured
95
- let data = generate_test_data(1000);
96
-
97
- b.iter(|| {
98
- // black_box the input reference
99
- let result = process(black_box(&data));
100
- black_box(result)
101
- });
102
- });
103
- }
104
- ```
105
-
106
- ## Pattern: Benchmark Multiple Inputs
107
-
108
- ```rust
109
- fn benchmark_sizes(c: &mut Criterion) {
110
- let mut group = c.benchmark_group("scaling");
111
-
112
- for size in [100, 1000, 10000] {
113
- let data = generate_data(size);
114
-
115
- group.bench_with_input(
116
- BenchmarkId::from_parameter(size),
117
- &data,
118
- |b, data| {
119
- b.iter(|| process(black_box(data)))
120
- },
121
- );
122
- }
123
- group.finish();
124
- }
125
- ```
126
-
127
- ## Common Mistakes
128
-
129
- ```rust
130
- // WRONG: black_box inside loop does nothing useful
131
- for _ in 0..1000 {
132
- black_box(()); // Doesn't help
133
- compute();
134
- }
135
-
136
- // RIGHT: black_box the computation result
137
- for _ in 0..1000 {
138
- black_box(compute());
139
- }
140
-
141
- // WRONG: Only blocking output, not input
142
- let x = 42; // Constant, may be optimized
143
- black_box(expensive(x));
144
-
145
- // RIGHT: Block both
146
- black_box(expensive(black_box(42)));
147
- ```
148
-
149
- ## See Also
150
-
151
- - [test-criterion-bench](./test-criterion-bench.md) - Using Criterion
152
- - [perf-profile-first](./perf-profile-first.md) - Profile before optimize
153
- - [perf-release-profile](./perf-release-profile.md) - Release settings
@@ -1,136 +0,0 @@
1
- # perf-chain-avoid
2
-
3
- > Avoid chain in hot loops
4
-
5
- ## Why It Matters
6
-
7
- `Iterator::chain()` adds overhead for checking which iterator is active on every `.next()` call. In hot loops, this branch prediction overhead can impact performance. For performance-critical code, prefer single iterators or pre-combined collections.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Chain in hot inner loop
13
- fn process_hot_path(a: &[i32], b: &[i32]) -> i64 {
14
- let mut sum = 0i64;
15
-
16
- // Called millions of times
17
- for _ in 0..1_000_000 {
18
- for x in a.iter().chain(b.iter()) { // Branch every iteration
19
- sum += *x as i64;
20
- }
21
- }
22
- sum
23
- }
24
-
25
- // Chaining multiple small slices in tight loop
26
- fn combine_results(parts: &[&[u8]]) -> Vec<u8> {
27
- let mut result = Vec::new();
28
- for part in parts {
29
- for byte in std::iter::once(&0u8).chain(part.iter()) {
30
- result.push(*byte);
31
- }
32
- }
33
- result
34
- }
35
- ```
36
-
37
- ## Good
38
-
39
- ```rust
40
- // Separate loops - branch-free inner loops
41
- fn process_hot_path(a: &[i32], b: &[i32]) -> i64 {
42
- let mut sum = 0i64;
43
-
44
- for _ in 0..1_000_000 {
45
- for x in a {
46
- sum += *x as i64;
47
- }
48
- for x in b {
49
- sum += *x as i64;
50
- }
51
- }
52
- sum
53
- }
54
-
55
- // Pre-combine outside hot loop
56
- fn combine_results(parts: &[&[u8]]) -> Vec<u8> {
57
- let mut result = Vec::new();
58
- for part in parts {
59
- result.push(0u8);
60
- result.extend_from_slice(part);
61
- }
62
- result
63
- }
64
- ```
65
-
66
- ## When Chain Is Fine
67
-
68
- Chain is perfectly acceptable when:
69
-
70
- ```rust
71
- // One-time iteration, not in hot path
72
- fn collect_all(a: Vec<i32>, b: Vec<i32>) -> Vec<i32> {
73
- a.into_iter().chain(b).collect()
74
- }
75
-
76
- // Lazy evaluation with short-circuit
77
- fn find_in_either(a: &[Item], b: &[Item], target: i32) -> Option<&Item> {
78
- a.iter().chain(b.iter()).find(|x| x.id == target)
79
- }
80
-
81
- // Small number of elements
82
- fn get_prefixes() -> impl Iterator<Item = &'static str> {
83
- ["Mr.", "Mrs.", "Dr."].iter().copied()
84
- .chain(["Prof."].iter().copied())
85
- }
86
- ```
87
-
88
- ## Alternative Patterns
89
-
90
- ### Pre-allocate and Extend
91
-
92
- ```rust
93
- fn merge_slices(slices: &[&[i32]]) -> Vec<i32> {
94
- let total: usize = slices.iter().map(|s| s.len()).sum();
95
- let mut result = Vec::with_capacity(total);
96
- for slice in slices {
97
- result.extend_from_slice(slice);
98
- }
99
- result
100
- }
101
- ```
102
-
103
- ### Use append for Vecs
104
-
105
- ```rust
106
- fn combine_vecs(mut a: Vec<i32>, mut b: Vec<i32>) -> Vec<i32> {
107
- a.append(&mut b); // Moves elements, no reallocation if a has capacity
108
- a
109
- }
110
- ```
111
-
112
- ### Flatten Instead of Chain
113
-
114
- ```rust
115
- // Instead of: a.iter().chain(b.iter()).chain(c.iter())
116
- let all = [a, b, c];
117
- for item in all.iter().flat_map(|slice| slice.iter()) {
118
- process(item);
119
- }
120
- ```
121
-
122
- ## Performance Impact
123
-
124
- | Pattern | Per-Item Overhead |
125
- |---------|-------------------|
126
- | Single iterator | None |
127
- | `chain(a, b)` | 1 branch per item |
128
- | `chain(a, b, c)` | 2 branches per item |
129
- | Nested chains | Compounds |
130
- | Separate loops | None (but code duplication) |
131
-
132
- ## See Also
133
-
134
- - [perf-iter-over-index](./perf-iter-over-index.md) - Prefer iterators
135
- - [perf-extend-batch](./perf-extend-batch.md) - Batch insertions
136
- - [opt-cache-friendly](./opt-cache-friendly.md) - Cache-friendly patterns