agy-superpowers 5.2.1 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/patches/skills-patches.md +23 -0
  4. package/template/agent/rules/scratch-scripts.md +37 -0
  5. package/template/agent/rules/superpowers.md +6 -50
  6. package/template/agent/skills/brainstorming/SKILL.md +4 -3
  7. package/template/agent/skills/brainstorming/visual-companion.md +2 -3
  8. package/template/agent/skills/finishing-a-development-branch/SKILL.md +11 -16
  9. package/template/agent/skills/subagent-driven-development/SKILL.md +16 -0
  10. package/template/agent/skills/subagent-driven-development/implementer-prompt.md +4 -3
  11. package/template/agent/skills/using-git-worktrees/SKILL.md +3 -2
  12. package/template/agent/skills/using-superpowers/SKILL.md +8 -6
  13. package/template/agent/skills/using-superpowers/references/copilot-tools.md +52 -0
  14. package/template/agent/skills/writing-plans/SKILL.md +5 -3
  15. package/template/agent/skills/writing-skills/SKILL.md +1 -1
  16. package/template/agent/superpowers-version.json +2 -2
  17. package/template/agent/tmp/agent-config-backup.yml +9 -0
  18. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  19. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  20. package/template/agent/skills/api-design/SKILL.md +0 -193
  21. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  22. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  23. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  24. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  25. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  26. package/template/agent/skills/community-manager/SKILL.md +0 -115
  27. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  28. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  29. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  30. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  31. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  32. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  33. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  34. package/template/agent/skills/game-design/SKILL.md +0 -194
  35. package/template/agent/skills/game-developer/SKILL.md +0 -175
  36. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  37. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  38. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  39. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  40. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  41. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  42. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  43. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  44. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  45. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  46. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  47. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  48. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  49. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  50. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  64. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  79. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  80. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  94. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  95. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  105. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  106. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  117. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  118. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  128. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  129. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  143. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  144. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  159. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  160. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  171. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  172. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  183. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  184. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  194. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  195. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  206. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  218. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  228. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  229. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  230. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  231. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  232. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  233. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,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