agy-superpowers 5.2.2 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/scratch-scripts.md +37 -0
  4. package/template/agent/rules/superpowers.md +4 -51
  5. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  6. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  7. package/template/agent/skills/api-design/SKILL.md +0 -193
  8. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  9. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  10. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  11. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  12. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  13. package/template/agent/skills/community-manager/SKILL.md +0 -115
  14. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  15. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  16. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  17. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  18. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  19. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  20. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  21. package/template/agent/skills/game-design/SKILL.md +0 -194
  22. package/template/agent/skills/game-developer/SKILL.md +0 -175
  23. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  24. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  25. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  26. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  27. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  28. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  29. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  30. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  31. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  32. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  33. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  34. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  35. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  36. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  37. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  38. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  39. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  40. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  41. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  42. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  43. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  44. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  45. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  46. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  47. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  48. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  53. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  54. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  55. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  56. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  57. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  58. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  59. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  60. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  61. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  62. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  63. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  68. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  69. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  70. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  71. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  72. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  73. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  74. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  75. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  76. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  77. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  78. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  83. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  84. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  85. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  86. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  87. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  88. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  89. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  90. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  91. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  92. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  93. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  94. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  95. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  96. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  97. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  98. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  99. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  100. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  101. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  102. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  103. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  104. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  106. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  107. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  108. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  109. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  110. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  111. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  113. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  114. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  115. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  116. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  117. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  118. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  119. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  120. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  121. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  122. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  123. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  124. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  125. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  126. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  127. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  132. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  133. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  134. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  135. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  136. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  137. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  138. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  139. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  140. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  141. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  148. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  149. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  150. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  151. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  152. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  153. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  154. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  155. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  156. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  157. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  158. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  160. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  161. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  162. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  163. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  164. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  165. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  166. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  167. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  168. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  169. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  170. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  172. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  173. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  174. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  175. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  176. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  177. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  179. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  180. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  181. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  182. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  183. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  184. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  185. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  186. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  187. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  188. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  189. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  190. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  191. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  192. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  193. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  194. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  195. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  196. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  197. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  198. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  199. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  200. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  201. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  202. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  203. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  204. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  207. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  208. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  210. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  211. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  212. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  213. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  214. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  215. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  216. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  217. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  218. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  219. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  220. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,105 +0,0 @@
1
- # own-mutex-interior
2
-
3
- > Use `Mutex<T>` for interior mutability across threads
4
-
5
- ## Why It Matters
6
-
7
- When you need shared mutable state across threads, `Mutex<T>` provides safe interior mutability with synchronization. Unlike `RefCell`, `Mutex` is `Send + Sync` and uses OS-level locking to ensure only one thread can access the data at a time.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use std::cell::RefCell;
13
- use std::sync::Arc;
14
-
15
- // RefCell is !Sync - this won't compile
16
- let shared = Arc::new(RefCell::new(vec![]));
17
-
18
- // ERROR: RefCell cannot be shared between threads safely
19
- std::thread::spawn({
20
- let shared = shared.clone();
21
- move || shared.borrow_mut().push(1)
22
- });
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- use std::sync::{Arc, Mutex};
29
-
30
- let shared = Arc::new(Mutex::new(vec![]));
31
-
32
- let handles: Vec<_> = (0..10).map(|i| {
33
- let shared = shared.clone();
34
- std::thread::spawn(move || {
35
- let mut data = shared.lock().unwrap();
36
- data.push(i);
37
- })
38
- }).collect();
39
-
40
- for handle in handles {
41
- handle.join().unwrap();
42
- }
43
-
44
- println!("{:?}", shared.lock().unwrap()); // All values present
45
- ```
46
-
47
- ## Mutex Poisoning
48
-
49
- If a thread panics while holding a lock, the mutex becomes "poisoned":
50
-
51
- ```rust
52
- use std::sync::{Arc, Mutex};
53
-
54
- let mutex = Arc::new(Mutex::new(0));
55
-
56
- // Handle poisoning gracefully
57
- match mutex.lock() {
58
- Ok(guard) => println!("Value: {}", *guard),
59
- Err(poisoned) => {
60
- // Recover the data anyway
61
- let guard = poisoned.into_inner();
62
- println!("Recovered value: {}", *guard);
63
- }
64
- }
65
-
66
- // Or ignore poisoning (use with caution)
67
- let guard = mutex.lock().unwrap_or_else(|e| e.into_inner());
68
- ```
69
-
70
- ## Prefer parking_lot::Mutex
71
-
72
- For better performance, consider `parking_lot::Mutex`:
73
-
74
- ```rust
75
- use parking_lot::Mutex;
76
- use std::sync::Arc;
77
-
78
- let shared = Arc::new(Mutex::new(vec![]));
79
-
80
- // No poisoning, no Result to unwrap
81
- let mut data = shared.lock();
82
- data.push(42);
83
- // Lock automatically released when guard drops
84
- ```
85
-
86
- Benefits of `parking_lot`:
87
- - No poisoning (returns guard directly)
88
- - Smaller size (1 byte vs 40+ bytes)
89
- - Better performance under contention
90
- - Fair locking option available
91
-
92
- ## When to Use What
93
-
94
- | Type | Threading | Overhead | Use Case |
95
- |------|-----------|----------|----------|
96
- | `RefCell<T>` | Single | Minimal | Interior mutability, same thread |
97
- | `Mutex<T>` | Multi | Locking | Shared mutable state across threads |
98
- | `RwLock<T>` | Multi | Locking | Many readers, few writers |
99
- | `parking_lot::Mutex` | Multi | Less | Drop-in std::Mutex replacement |
100
-
101
- ## See Also
102
-
103
- - [own-rwlock-readers](./own-rwlock-readers.md) - When reads dominate writes
104
- - [own-refcell-interior](./own-refcell-interior.md) - Single-threaded alternative
105
- - [async-no-lock-await](./async-no-lock-await.md) - Avoiding locks across await points
@@ -1,65 +0,0 @@
1
- # own-rc-single-thread
2
-
3
- > Use `Rc<T>` for shared ownership in single-threaded contexts
4
-
5
- ## Why It Matters
6
-
7
- `Rc<T>` (Reference Counted) provides shared ownership without the atomic overhead of `Arc<T>`. In single-threaded code, `Rc` is faster because it uses non-atomic reference counting. Using `Arc` when you don't need thread-safety wastes CPU cycles on unnecessary synchronization.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use std::sync::Arc;
13
-
14
- // Single-threaded application using Arc unnecessarily
15
- fn build_tree() -> Arc<Node> {
16
- let root = Arc::new(Node::new("root"));
17
- let child1 = Arc::new(Node::new("child1"));
18
- let child2 = Arc::new(Node::new("child2"));
19
-
20
- // All in same thread, but paying atomic overhead
21
- root.add_child(child1.clone());
22
- root.add_child(child2.clone());
23
- root
24
- }
25
- ```
26
-
27
- Atomic operations have measurable overhead even without contention.
28
-
29
- ## Good
30
-
31
- ```rust
32
- use std::rc::Rc;
33
-
34
- // Single-threaded: use Rc for zero atomic overhead
35
- fn build_tree() -> Rc<Node> {
36
- let root = Rc::new(Node::new("root"));
37
- let child1 = Rc::new(Node::new("child1"));
38
- let child2 = Rc::new(Node::new("child2"));
39
-
40
- root.add_child(child1.clone());
41
- root.add_child(child2.clone());
42
- root
43
- }
44
-
45
- // Compiler enforces single-thread: Rc is !Send + !Sync
46
- // Attempting to send across threads = compile error
47
- ```
48
-
49
- ## Decision Guide
50
-
51
- | Scenario | Use |
52
- |----------|-----|
53
- | Single-threaded, shared ownership | `Rc<T>` |
54
- | Multi-threaded, shared ownership | `Arc<T>` |
55
- | Single owner, might need multiple later | Start with `Rc`, upgrade if needed |
56
- | Library code, unknown threading model | `Arc<T>` (safer default) |
57
-
58
- ## Evidence
59
-
60
- The Rust standard library itself uses `Rc` extensively in single-threaded contexts like the `std::rc` module documentation examples.
61
-
62
- ## See Also
63
-
64
- - [own-arc-shared](./own-arc-shared.md) - When you need thread-safe sharing
65
- - [own-refcell-interior](./own-refcell-interior.md) - Combining Rc with interior mutability
@@ -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