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,154 +0,0 @@
1
- # test-tokio-async
2
-
3
- > Use `#[tokio::test]` for async tests
4
-
5
- ## Why It Matters
6
-
7
- Async functions can't be called directly—they need a runtime to drive them. `#[tokio::test]` provides a Tokio runtime for your test, handling setup automatically. This is simpler than manually creating a runtime and essential for testing async code.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Won't compile - async fn can't be called without runtime
13
- #[test]
14
- async fn test_async_function() { // Error!
15
- let result = fetch_data().await;
16
- assert!(result.is_ok());
17
- }
18
-
19
- // Manual runtime - verbose and error-prone
20
- #[test]
21
- fn test_async_function() {
22
- let rt = tokio::runtime::Runtime::new().unwrap();
23
- rt.block_on(async {
24
- let result = fetch_data().await;
25
- assert!(result.is_ok());
26
- });
27
- }
28
- ```
29
-
30
- ## Good
31
-
32
- ```rust
33
- #[tokio::test]
34
- async fn test_async_function() {
35
- let result = fetch_data().await;
36
- assert!(result.is_ok());
37
- }
38
-
39
- #[tokio::test]
40
- async fn test_concurrent_operations() {
41
- let (a, b) = tokio::join!(
42
- fetch_user(1),
43
- fetch_user(2),
44
- );
45
- assert!(a.is_ok());
46
- assert!(b.is_ok());
47
- }
48
- ```
49
-
50
- ## Runtime Configuration
51
-
52
- ```rust
53
- // Multi-threaded runtime (default)
54
- #[tokio::test]
55
- async fn test_default_runtime() {
56
- // Uses multi-thread runtime
57
- }
58
-
59
- // Single-threaded (current_thread)
60
- #[tokio::test(flavor = "current_thread")]
61
- async fn test_single_threaded() {
62
- // Simpler, deterministic
63
- }
64
-
65
- // With specific thread count
66
- #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
67
- async fn test_with_workers() {
68
- // Exactly 2 worker threads
69
- }
70
-
71
- // With time control
72
- #[tokio::test(start_paused = true)]
73
- async fn test_with_time_control() {
74
- // Time starts paused for deterministic testing
75
- tokio::time::advance(Duration::from_secs(60)).await;
76
- }
77
- ```
78
-
79
- ## Testing Timeouts
80
-
81
- ```rust
82
- use tokio::time::{timeout, Duration};
83
-
84
- #[tokio::test]
85
- async fn test_operation_completes_in_time() {
86
- let result = timeout(
87
- Duration::from_secs(5),
88
- slow_operation()
89
- ).await;
90
-
91
- assert!(result.is_ok(), "Operation timed out");
92
- }
93
-
94
- #[tokio::test]
95
- async fn test_timeout_triggers() {
96
- let result = timeout(
97
- Duration::from_millis(100),
98
- never_completes()
99
- ).await;
100
-
101
- assert!(result.is_err(), "Expected timeout");
102
- }
103
- ```
104
-
105
- ## Testing Channels
106
-
107
- ```rust
108
- use tokio::sync::mpsc;
109
-
110
- #[tokio::test]
111
- async fn test_channel_communication() {
112
- let (tx, mut rx) = mpsc::channel(10);
113
-
114
- tokio::spawn(async move {
115
- tx.send("hello").await.unwrap();
116
- tx.send("world").await.unwrap();
117
- });
118
-
119
- assert_eq!(rx.recv().await, Some("hello"));
120
- assert_eq!(rx.recv().await, Some("world"));
121
- assert_eq!(rx.recv().await, None);
122
- }
123
- ```
124
-
125
- ## Testing with Mocks
126
-
127
- ```rust
128
- use mockall::*;
129
-
130
- #[automock]
131
- #[async_trait::async_trait]
132
- trait Database {
133
- async fn get_user(&self, id: u64) -> Option<User>;
134
- }
135
-
136
- #[tokio::test]
137
- async fn test_with_mock_database() {
138
- let mut mock = MockDatabase::new();
139
- mock.expect_get_user()
140
- .with(eq(42))
141
- .returning(|_| Some(User { id: 42, name: "Alice".into() }));
142
-
143
- let service = UserService::new(mock);
144
- let user = service.find_user(42).await;
145
-
146
- assert_eq!(user.unwrap().name, "Alice");
147
- }
148
- ```
149
-
150
- ## See Also
151
-
152
- - [async-tokio-runtime](./async-tokio-runtime.md) - Runtime configuration
153
- - [test-mock-traits](./test-mock-traits.md) - Mocking async traits
154
- - [test-fixture-raii](./test-fixture-raii.md) - Async test cleanup
@@ -1,127 +0,0 @@
1
- # test-use-super
2
-
3
- > Use `use super::*;` in test modules to access parent module items
4
-
5
- ## Why It Matters
6
-
7
- The test module is a child of the module being tested. `use super::*` imports all items from the parent module, including private ones. This gives tests access to both public API and internal implementation details for thorough testing.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Verbose imports
13
- #[cfg(test)]
14
- mod tests {
15
- use crate::my_module::public_function;
16
- use crate::my_module::MyStruct;
17
- // Can't access private items this way!
18
-
19
- #[test]
20
- fn test_function() {
21
- let result = public_function();
22
- // ...
23
- }
24
- }
25
- ```
26
-
27
- ## Good
28
-
29
- ```rust
30
- // src/my_module.rs
31
- pub struct PublicStruct { ... }
32
- struct PrivateStruct { ... } // Private
33
-
34
- pub fn public_function() -> i32 { ... }
35
- fn private_helper() -> i32 { ... } // Private
36
-
37
- #[cfg(test)]
38
- mod tests {
39
- use super::*; // Imports everything from parent
40
-
41
- #[test]
42
- fn test_public_struct() {
43
- let s = PublicStruct::new();
44
- // ...
45
- }
46
-
47
- #[test]
48
- fn test_private_struct() {
49
- let s = PrivateStruct::new(); // Can access private!
50
- // ...
51
- }
52
-
53
- #[test]
54
- fn test_private_helper() {
55
- assert_eq!(private_helper(), 42); // Can test private!
56
- }
57
- }
58
- ```
59
-
60
- ## Selective Imports
61
-
62
- ```rust
63
- #[cfg(test)]
64
- mod tests {
65
- // When you want to be explicit
66
- use super::{parse, ParseError, Token};
67
-
68
- // Or import all plus test utilities
69
- use super::*;
70
- use std::fs;
71
- use tempfile::TempDir;
72
-
73
- #[test]
74
- fn test_parse() { ... }
75
- }
76
- ```
77
-
78
- ## Nested Modules
79
-
80
- ```rust
81
- mod outer {
82
- pub fn outer_fn() -> i32 { 1 }
83
-
84
- mod inner {
85
- pub fn inner_fn() -> i32 { 2 }
86
-
87
- #[cfg(test)]
88
- mod tests {
89
- use super::*; // Gets inner's items
90
- use super::super::*; // Gets outer's items
91
-
92
- #[test]
93
- fn test_inner() {
94
- assert_eq!(inner_fn(), 2);
95
- assert_eq!(outer_fn(), 1);
96
- }
97
- }
98
- }
99
- }
100
- ```
101
-
102
- ## With External Dependencies
103
-
104
- ```rust
105
- #[cfg(test)]
106
- mod tests {
107
- use super::*;
108
-
109
- // Test-only dependencies
110
- use proptest::prelude::*;
111
- use mockall::predicate::*;
112
-
113
- proptest! {
114
- #[test]
115
- fn test_property(s: String) {
116
- let result = process(&s);
117
- prop_assert!(result.is_ok());
118
- }
119
- }
120
- }
121
- ```
122
-
123
- ## See Also
124
-
125
- - [test-cfg-test-module](./test-cfg-test-module.md) - Test module structure
126
- - [test-integration-dir](./test-integration-dir.md) - Integration tests
127
- - [proj-pub-crate-internal](./proj-pub-crate-internal.md) - Visibility modifiers
@@ -1,154 +0,0 @@
1
- # type-enum-states
2
-
3
- > Use enums for mutually exclusive states
4
-
5
- ## Why It Matters
6
-
7
- When a value can be in exactly one of several states, an enum makes invalid states unrepresentable. The compiler ensures all states are handled. Contrast with boolean flags or optional fields that can represent impossible combinations.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Connection {
13
- is_connected: bool,
14
- is_authenticated: bool,
15
- is_disconnected: bool, // Can all three be true? False?
16
- socket: Option<TcpStream>,
17
- credentials: Option<Credentials>,
18
- }
19
-
20
- // Possible invalid states:
21
- // - is_connected && is_disconnected (contradiction)
22
- // - is_authenticated && !is_connected (impossible)
23
- // - socket is None but is_connected is true (inconsistent)
24
- ```
25
-
26
- ## Good
27
-
28
- ```rust
29
- enum ConnectionState {
30
- Disconnected,
31
- Connecting { address: SocketAddr },
32
- Connected { socket: TcpStream },
33
- Authenticated { socket: TcpStream, session: Session },
34
- Failed { error: ConnectionError },
35
- }
36
-
37
- struct Connection {
38
- state: ConnectionState,
39
- }
40
-
41
- // Impossible states are unrepresentable
42
- // Each state has exactly the data it needs
43
- ```
44
-
45
- ## Pattern Matching Ensures Completeness
46
-
47
- ```rust
48
- fn handle_connection(conn: &Connection) {
49
- match &conn.state {
50
- ConnectionState::Disconnected => {
51
- println!("Not connected");
52
- }
53
- ConnectionState::Connecting { address } => {
54
- println!("Connecting to {}", address);
55
- }
56
- ConnectionState::Connected { socket } => {
57
- println!("Connected, not authenticated");
58
- }
59
- ConnectionState::Authenticated { socket, session } => {
60
- println!("Authenticated as {}", session.user);
61
- }
62
- ConnectionState::Failed { error } => {
63
- println!("Failed: {}", error);
64
- }
65
- }
66
- // Compiler error if any state is missing
67
- }
68
- ```
69
-
70
- ## State Transitions
71
-
72
- ```rust
73
- impl Connection {
74
- fn connect(&mut self, addr: SocketAddr) -> Result<(), Error> {
75
- match &self.state {
76
- ConnectionState::Disconnected => {
77
- self.state = ConnectionState::Connecting { address: addr };
78
- Ok(())
79
- }
80
- _ => Err(Error::AlreadyConnected),
81
- }
82
- }
83
-
84
- fn on_connected(&mut self, socket: TcpStream) {
85
- if let ConnectionState::Connecting { .. } = &self.state {
86
- self.state = ConnectionState::Connected { socket };
87
- }
88
- }
89
-
90
- fn authenticate(&mut self, creds: Credentials) -> Result<(), Error> {
91
- match std::mem::replace(&mut self.state, ConnectionState::Disconnected) {
92
- ConnectionState::Connected { socket } => {
93
- let session = perform_auth(&socket, creds)?;
94
- self.state = ConnectionState::Authenticated { socket, session };
95
- Ok(())
96
- }
97
- other => {
98
- self.state = other;
99
- Err(Error::NotConnected)
100
- }
101
- }
102
- }
103
- }
104
- ```
105
-
106
- ## Result and Option as State Enums
107
-
108
- ```rust
109
- // Option<T> is an enum for "might not exist"
110
- enum Option<T> {
111
- Some(T),
112
- None,
113
- }
114
-
115
- // Result<T, E> is an enum for "might have failed"
116
- enum Result<T, E> {
117
- Ok(T),
118
- Err(E),
119
- }
120
-
121
- // Use these instead of nullable/sentinel values
122
- fn find_user(id: u64) -> Option<User> { ... }
123
- fn parse_config(s: &str) -> Result<Config, ParseError> { ... }
124
- ```
125
-
126
- ## Avoid Boolean Flags
127
-
128
- ```rust
129
- // Bad: boolean flags
130
- struct Task {
131
- is_running: bool,
132
- is_completed: bool,
133
- is_failed: bool,
134
- error: Option<Error>,
135
- }
136
-
137
- // Good: enum state
138
- enum TaskState {
139
- Pending,
140
- Running { started_at: Instant },
141
- Completed { result: Output },
142
- Failed { error: Error },
143
- }
144
-
145
- struct Task {
146
- state: TaskState,
147
- }
148
- ```
149
-
150
- ## See Also
151
-
152
- - [api-typestate](./api-typestate.md) - Type-level state machines
153
- - [api-non-exhaustive](./api-non-exhaustive.md) - Forward-compatible enums
154
- - [type-option-nullable](./type-option-nullable.md) - Option for optional values
@@ -1,142 +0,0 @@
1
- # type-generic-bounds
2
-
3
- > Add trait bounds only where needed, prefer where clauses for readability
4
-
5
- ## Why It Matters
6
-
7
- Trait bounds constrain what types can be used with generic code. Adding unnecessary bounds limits flexibility. Adding bounds in the right place (impl vs function vs where clause) affects usability and readability. Well-placed bounds keep APIs flexible while ensuring type safety.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Bounds on struct definition - limits all uses
13
- struct Container<T: Clone + Debug> { // Even storage requires Clone?
14
- items: Vec<T>,
15
- }
16
-
17
- // Inline bounds make signature hard to read
18
- fn process<T: Clone + Debug + Send + Sync + 'static, E: Error + Send + Clone>(
19
- value: T
20
- ) -> Result<T, E> { ... }
21
-
22
- // Redundant bounds
23
- fn print_twice<T: Clone + Debug>(value: T)
24
- where
25
- T: Clone, // Already specified above
26
- { ... }
27
- ```
28
-
29
- ## Good
30
-
31
- ```rust
32
- // No bounds on struct - store anything
33
- struct Container<T> {
34
- items: Vec<T>,
35
- }
36
-
37
- // Bounds only on impls that need them
38
- impl<T: Clone> Container<T> {
39
- fn duplicate(&self) -> Self {
40
- Container { items: self.items.clone() }
41
- }
42
- }
43
-
44
- impl<T: Debug> Container<T> {
45
- fn debug_print(&self) {
46
- println!("{:?}", self.items);
47
- }
48
- }
49
-
50
- // Where clause for readability
51
- fn process<T, E>(value: T) -> Result<T, E>
52
- where
53
- T: Clone + Debug + Send + Sync + 'static,
54
- E: Error + Send + Clone,
55
- { ... }
56
- ```
57
-
58
- ## Bound Placement
59
-
60
- ```rust
61
- // On struct: affects all uses of the type
62
- struct MustBeClone<T: Clone> { data: T } // Rarely needed
63
-
64
- // On impl: affects specific functionality
65
- impl<T: Clone> Container<T> { ... } // Common pattern
66
-
67
- // On function: affects that function only
68
- fn requires_send<T: Send>(value: T) { ... }
69
-
70
- // Recommendation: start with no bounds, add as needed
71
- ```
72
-
73
- ## Where Clause Benefits
74
-
75
- ```rust
76
- // Inline: hard to read
77
- fn complex<T: Clone + Debug + Send, U: AsRef<str> + Into<String>>(t: T, u: U) { }
78
-
79
- // Where clause: clear and scannable
80
- fn complex<T, U>(t: T, u: U)
81
- where
82
- T: Clone + Debug + Send,
83
- U: AsRef<str> + Into<String>,
84
- { }
85
-
86
- // Essential for complex bounds
87
- fn foo<T, U>(t: T, u: U)
88
- where
89
- T: Iterator<Item = U>,
90
- U: Clone + Into<String>,
91
- Vec<U>: Debug, // Bounds on expressions
92
- { }
93
- ```
94
-
95
- ## Implied Bounds
96
-
97
- ```rust
98
- // Supertrait bounds are implied
99
- trait Foo: Clone + Debug {}
100
-
101
- fn process<T: Foo>(value: T) {
102
- // T: Clone and T: Debug are implied by T: Foo
103
- let cloned = value.clone();
104
- println!("{:?}", cloned);
105
- }
106
-
107
- // Associated type bounds
108
- fn process<I>(iter: I)
109
- where
110
- I: Iterator,
111
- I::Item: Clone, // Bound on associated type
112
- { }
113
- ```
114
-
115
- ## Conditional Trait Implementation
116
-
117
- ```rust
118
- struct Wrapper<T>(T);
119
-
120
- // Implement Clone only when T: Clone
121
- impl<T: Clone> Clone for Wrapper<T> {
122
- fn clone(&self) -> Self {
123
- Wrapper(self.0.clone())
124
- }
125
- }
126
-
127
- // Implement Debug only when T: Debug
128
- impl<T: Debug> Debug for Wrapper<T> {
129
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
130
- f.debug_tuple("Wrapper").field(&self.0).finish()
131
- }
132
- }
133
-
134
- // Wrapper<i32> is Clone + Debug
135
- // Wrapper<NonCloneable> is neither
136
- ```
137
-
138
- ## See Also
139
-
140
- - [api-impl-into](./api-impl-into.md) - Using Into bounds
141
- - [api-impl-asref](./api-impl-asref.md) - Using AsRef bounds
142
- - [name-type-param-single](./name-type-param-single.md) - Type parameter naming
@@ -1,146 +0,0 @@
1
- # type-never-diverge
2
-
3
- > Use `!` (never type) for functions that never return
4
-
5
- ## Why It Matters
6
-
7
- The never type `!` indicates a function will never return normally—it either loops forever, panics, or exits the process. This helps the compiler understand control flow and enables `!` to coerce to any type, making it useful in match arms and expressions.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Return type doesn't indicate non-returning
13
- fn infinite_loop() {
14
- loop {
15
- process_events();
16
- }
17
- // Implicit () return type, but never returns
18
- }
19
-
20
- // Using Option when it always panics
21
- fn unreachable_code() -> Option<()> {
22
- panic!("This should never be called");
23
- }
24
- ```
25
-
26
- ## Good
27
-
28
- ```rust
29
- // ! indicates function never returns
30
- fn infinite_loop() -> ! {
31
- loop {
32
- process_events();
33
- }
34
- }
35
-
36
- fn abort_with_error(msg: &str) -> ! {
37
- eprintln!("Fatal error: {}", msg);
38
- std::process::exit(1);
39
- }
40
-
41
- fn panic_handler() -> ! {
42
- panic!("Unexpected state");
43
- }
44
- ```
45
-
46
- ## Coercion to Any Type
47
-
48
- ```rust
49
- // ! coerces to any type
50
- fn get_value(opt: Option<i32>) -> i32 {
51
- match opt {
52
- Some(v) => v,
53
- None => panic!("No value"), // panic! returns !, coerces to i32
54
- }
55
- }
56
-
57
- // Useful in Result handling
58
- fn must_get_config() -> Config {
59
- match load_config() {
60
- Ok(c) => c,
61
- Err(e) => {
62
- log_error(&e);
63
- std::process::exit(1) // Returns !, coerces to Config
64
- }
65
- }
66
- }
67
- ```
68
-
69
- ## Standard Library Examples
70
-
71
- ```rust
72
- // std::process::exit
73
- pub fn exit(code: i32) -> !
74
-
75
- // panic! macro
76
- // Expands to an expression of type !
77
-
78
- // std::hint::unreachable_unchecked
79
- pub unsafe fn unreachable_unchecked() -> !
80
-
81
- // loop {} with no break
82
- fn forever() -> ! {
83
- loop {}
84
- }
85
- ```
86
-
87
- ## In Match Expressions
88
-
89
- ```rust
90
- enum State {
91
- Running,
92
- Stopped,
93
- Error,
94
- }
95
-
96
- fn get_status(state: &State) -> &str {
97
- match state {
98
- State::Running => "running",
99
- State::Stopped => "stopped",
100
- State::Error => unreachable!(), // ! coerces to &str
101
- }
102
- }
103
-
104
- // With Result
105
- fn process(r: Result<Data, Error>) -> Data {
106
- match r {
107
- Ok(d) => d,
108
- Err(e) => panic!("Unexpected error: {}", e), // ! coerces to Data
109
- }
110
- }
111
- ```
112
-
113
- ## Diverging Closures
114
-
115
- ```rust
116
- // Closures that never return
117
- let handler: fn() -> ! = || {
118
- panic!("Handler called");
119
- };
120
-
121
- // In thread spawn
122
- std::thread::spawn(|| -> ! {
123
- loop {
124
- process_work();
125
- }
126
- });
127
- ```
128
-
129
- ## Current Limitations (Nightly)
130
-
131
- ```rust
132
- // Full ! type is nightly
133
- #![feature(never_type)]
134
-
135
- // Can use ! as type parameter
136
- type NeverResult = Result<(), !>; // Can never be Err
137
-
138
- // On stable, use std::convert::Infallible
139
- type StableNeverResult = Result<(), std::convert::Infallible>;
140
- ```
141
-
142
- ## See Also
143
-
144
- - [err-result-over-panic](./err-result-over-panic.md) - When to panic vs return Result
145
- - [type-result-fallible](./type-result-fallible.md) - Result for errors
146
- - [opt-cold-unlikely](./opt-cold-unlikely.md) - Marking unlikely paths