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,182 +0,0 @@
1
- # api-serde-optional
2
-
3
- > Make serde a feature flag, not a hard dependency for library crates
4
-
5
- ## Why It Matters
6
-
7
- Not all users of your library need serialization. Making serde a required dependency adds compile time and binary size for everyone. Feature flags let users opt-in to serde support only when needed, following Rust's philosophy of zero-cost abstractions and minimal dependencies.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Cargo.toml
13
- [dependencies]
14
- serde = { version = "1.0", features = ["derive"] }
15
-
16
- // lib.rs
17
- use serde::{Serialize, Deserialize};
18
-
19
- // Every user pays for serde, even if they don't need it
20
- #[derive(Serialize, Deserialize)]
21
- pub struct Config {
22
- pub name: String,
23
- pub value: i32,
24
- }
25
- ```
26
-
27
- ## Good
28
-
29
- ```rust
30
- // Cargo.toml
31
- [dependencies]
32
- serde = { version = "1.0", features = ["derive"], optional = true }
33
-
34
- [features]
35
- default = []
36
- serde = ["dep:serde"]
37
-
38
- // lib.rs
39
- #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
40
- pub struct Config {
41
- pub name: String,
42
- pub value: i32,
43
- }
44
-
45
- // Users opt-in:
46
- // my_crate = { version = "1.0", features = ["serde"] }
47
- ```
48
-
49
- ## Macro Pattern
50
-
51
- ```rust
52
- // Reusable macro for serde derives
53
- #[cfg(feature = "serde")]
54
- macro_rules! impl_serde {
55
- ($($t:ty),*) => {
56
- $(
57
- impl serde::Serialize for $t {
58
- // ...
59
- }
60
- impl<'de> serde::Deserialize<'de> for $t {
61
- // ...
62
- }
63
- )*
64
- };
65
- }
66
-
67
- #[cfg(not(feature = "serde"))]
68
- macro_rules! impl_serde {
69
- ($($t:ty),*) => {};
70
- }
71
-
72
- // Or use cfg_attr for derived impls
73
- #[derive(Debug, Clone)]
74
- #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75
- pub struct Point {
76
- pub x: f64,
77
- pub y: f64,
78
- }
79
- ```
80
-
81
- ## Feature Documentation
82
-
83
- ```rust
84
- // lib.rs
85
-
86
- //! # Features
87
- //!
88
- //! - `serde`: Enables `Serialize` and `Deserialize` implementations for all types.
89
- //!
90
- //! # Example with serde
91
- //!
92
- //! ```toml
93
- //! [dependencies]
94
- //! my_crate = { version = "1.0", features = ["serde"] }
95
- //! ```
96
-
97
- #![cfg_attr(docsrs, feature(doc_cfg))]
98
-
99
- /// A configuration type.
100
- ///
101
- /// When the `serde` feature is enabled, this type implements
102
- /// `Serialize` and `Deserialize`.
103
- #[derive(Debug, Clone)]
104
- #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
105
- #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
106
- pub struct Config {
107
- pub name: String,
108
- }
109
- ```
110
-
111
- ## Multiple Optional Dependencies
112
-
113
- ```rust
114
- // Cargo.toml
115
- [dependencies]
116
- serde = { version = "1.0", features = ["derive"], optional = true }
117
- rkyv = { version = "0.7", optional = true }
118
- borsh = { version = "0.10", optional = true }
119
-
120
- [features]
121
- default = []
122
- serde = ["dep:serde"]
123
- rkyv = ["dep:rkyv"]
124
- borsh = ["dep:borsh"]
125
-
126
- // lib.rs
127
- #[derive(Debug, Clone)]
128
- #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
129
- #[cfg_attr(feature = "rkyv", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))]
130
- #[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
131
- pub struct Message {
132
- pub id: u64,
133
- pub content: String,
134
- }
135
- ```
136
-
137
- ## Testing with Features
138
-
139
- ```bash
140
- # Test without serde
141
- cargo test
142
-
143
- # Test with serde
144
- cargo test --features serde
145
-
146
- # Test all feature combinations
147
- cargo test --all-features
148
- ```
149
-
150
- ```rust
151
- // Test serde round-trip when feature enabled
152
- #[cfg(feature = "serde")]
153
- #[test]
154
- fn test_serde_roundtrip() {
155
- let config = Config { name: "test".into() };
156
- let json = serde_json::to_string(&config).unwrap();
157
- let parsed: Config = serde_json::from_str(&json).unwrap();
158
- assert_eq!(config, parsed);
159
- }
160
- ```
161
-
162
- ## When to Make Serde Required
163
-
164
- ```rust
165
- // ✅ Required: Library is about serialization
166
- // (e.g., json-schema, config-file parser)
167
- [dependencies]
168
- serde = "1.0"
169
-
170
- // ✅ Required: Domain heavily uses serde
171
- // (e.g., API client, data format library)
172
-
173
- // ❌ Optional: General-purpose utility library
174
- // ❌ Optional: Math/algorithm library
175
- // ❌ Optional: Most libraries!
176
- ```
177
-
178
- ## See Also
179
-
180
- - [proj-lib-main-split](./proj-lib-main-split.md) - Library structure
181
- - [api-common-traits](./api-common-traits.md) - Core trait implementations
182
- - [lint-deny-correctness](./lint-deny-correctness.md) - Feature testing
@@ -1,199 +0,0 @@
1
- # api-typestate
2
-
3
- > Use typestate pattern to encode state machine invariants in the type system
4
-
5
- ## Why It Matters
6
-
7
- State machines with runtime state checks ("are we connected?", "is the transaction started?") can have invalid transitions. The typestate pattern uses different types for each state, making invalid state transitions compile errors. The compiler enforces your state machine.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Connection {
13
- state: ConnectionState,
14
- socket: Option<TcpStream>,
15
- }
16
-
17
- enum ConnectionState {
18
- Disconnected,
19
- Connected,
20
- Authenticated,
21
- }
22
-
23
- impl Connection {
24
- fn send(&mut self, data: &[u8]) -> Result<(), Error> {
25
- // Runtime check - can fail if called in wrong state
26
- if self.state != ConnectionState::Authenticated {
27
- return Err(Error::NotAuthenticated);
28
- }
29
- self.socket.as_mut().unwrap().write_all(data)?;
30
- Ok(())
31
- }
32
-
33
- fn authenticate(&mut self, password: &str) -> Result<(), Error> {
34
- // Runtime check - can fail
35
- if self.state != ConnectionState::Connected {
36
- return Err(Error::NotConnected);
37
- }
38
- // ...
39
- }
40
- }
41
-
42
- // Bug: forgot to authenticate
43
- let mut conn = Connection::new();
44
- conn.connect()?;
45
- conn.send(b"data")?; // Runtime error: NotAuthenticated
46
- ```
47
-
48
- ## Good
49
-
50
- ```rust
51
- // Different types for each state
52
- struct Disconnected;
53
- struct Connected { socket: TcpStream }
54
- struct Authenticated { socket: TcpStream, session: Session }
55
-
56
- struct Connection<State> {
57
- state: State,
58
- }
59
-
60
- impl Connection<Disconnected> {
61
- fn new() -> Self {
62
- Connection { state: Disconnected }
63
- }
64
-
65
- fn connect(self, addr: &str) -> Result<Connection<Connected>, Error> {
66
- let socket = TcpStream::connect(addr)?;
67
- Ok(Connection { state: Connected { socket } })
68
- }
69
- }
70
-
71
- impl Connection<Connected> {
72
- fn authenticate(self, password: &str) -> Result<Connection<Authenticated>, Error> {
73
- let session = do_auth(&self.state.socket, password)?;
74
- Ok(Connection {
75
- state: Authenticated { socket: self.state.socket, session }
76
- })
77
- }
78
- }
79
-
80
- impl Connection<Authenticated> {
81
- fn send(&mut self, data: &[u8]) -> Result<(), Error> {
82
- // No runtime check needed - type guarantees we're authenticated
83
- self.state.socket.write_all(data)?;
84
- Ok(())
85
- }
86
- }
87
-
88
- // Bug: forgot to authenticate
89
- let conn = Connection::new();
90
- let conn = conn.connect("server:8080")?;
91
- conn.send(b"data"); // Compile error! send() not available on Connection<Connected>
92
-
93
- // Correct usage
94
- let conn = Connection::new();
95
- let conn = conn.connect("server:8080")?;
96
- let mut conn = conn.authenticate("secret")?;
97
- conn.send(b"data")?; // Works - type is Connection<Authenticated>
98
- ```
99
-
100
- ## Builder Typestate
101
-
102
- ```rust
103
- // Enforce required fields via typestate
104
- struct BuilderNoUrl;
105
- struct BuilderWithUrl { url: String }
106
-
107
- struct RequestBuilder<State> {
108
- state: State,
109
- timeout: Option<Duration>,
110
- }
111
-
112
- impl RequestBuilder<BuilderNoUrl> {
113
- fn new() -> Self {
114
- RequestBuilder {
115
- state: BuilderNoUrl,
116
- timeout: None,
117
- }
118
- }
119
-
120
- fn url(self, url: &str) -> RequestBuilder<BuilderWithUrl> {
121
- RequestBuilder {
122
- state: BuilderWithUrl { url: url.to_string() },
123
- timeout: self.timeout,
124
- }
125
- }
126
- }
127
-
128
- impl RequestBuilder<BuilderWithUrl> {
129
- fn timeout(mut self, t: Duration) -> Self {
130
- self.timeout = Some(t);
131
- self
132
- }
133
-
134
- // Only available once URL is set
135
- fn build(self) -> Request {
136
- Request {
137
- url: self.state.url,
138
- timeout: self.timeout,
139
- }
140
- }
141
- }
142
-
143
- // Compile error: build() not available
144
- let bad = RequestBuilder::new().build();
145
-
146
- // Correct: must set URL first
147
- let good = RequestBuilder::new()
148
- .url("https://example.com")
149
- .timeout(Duration::from_secs(30))
150
- .build();
151
- ```
152
-
153
- ## Transaction Example
154
-
155
- ```rust
156
- struct NotStarted;
157
- struct InProgress { tx_id: u64 }
158
- struct Committed;
159
-
160
- struct Transaction<State> {
161
- conn: Connection,
162
- state: State,
163
- }
164
-
165
- impl Transaction<NotStarted> {
166
- fn begin(conn: Connection) -> Result<Transaction<InProgress>, Error> {
167
- let tx_id = conn.execute("BEGIN")?;
168
- Ok(Transaction {
169
- conn,
170
- state: InProgress { tx_id },
171
- })
172
- }
173
- }
174
-
175
- impl Transaction<InProgress> {
176
- fn execute(&mut self, sql: &str) -> Result<(), Error> {
177
- self.conn.execute(sql)
178
- }
179
-
180
- fn commit(self) -> Result<Transaction<Committed>, Error> {
181
- self.conn.execute("COMMIT")?;
182
- Ok(Transaction {
183
- conn: self.conn,
184
- state: Committed,
185
- })
186
- }
187
-
188
- fn rollback(self) -> Connection {
189
- let _ = self.conn.execute("ROLLBACK");
190
- self.conn
191
- }
192
- }
193
- ```
194
-
195
- ## See Also
196
-
197
- - [api-builder-pattern](./api-builder-pattern.md) - Basic builder pattern
198
- - [api-parse-dont-validate](./api-parse-dont-validate.md) - Type-driven invariants
199
- - [api-sealed-trait](./api-sealed-trait.md) - Restricting trait implementations
@@ -1,175 +0,0 @@
1
- # async-bounded-channel
2
-
3
- > Use bounded channels to apply backpressure and prevent unbounded memory growth
4
-
5
- ## Why It Matters
6
-
7
- Unbounded channels grow without limit when producers outpace consumers. In production, this leads to memory exhaustion. Bounded channels apply backpressure—producers wait when the channel is full, naturally throttling the system. This prevents OOM and makes resource usage predictable.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- use tokio::sync::mpsc;
13
-
14
- // Unbounded channel - can grow forever
15
- let (tx, mut rx) = mpsc::unbounded_channel::<Message>();
16
-
17
- // Fast producer, slow consumer = unbounded memory growth
18
- tokio::spawn(async move {
19
- loop {
20
- let msg = generate_message();
21
- tx.send(msg).unwrap(); // Never blocks, never fails (until OOM)
22
- }
23
- });
24
-
25
- tokio::spawn(async move {
26
- while let Some(msg) = rx.recv().await {
27
- slow_process(msg).await; // Can't keep up
28
- }
29
- });
30
- // Memory grows unboundedly until crash
31
- ```
32
-
33
- ## Good
34
-
35
- ```rust
36
- use tokio::sync::mpsc;
37
-
38
- // Bounded channel - backpressure when full
39
- let (tx, mut rx) = mpsc::channel::<Message>(100); // Max 100 items
40
-
41
- // Producer waits when channel full
42
- tokio::spawn(async move {
43
- loop {
44
- let msg = generate_message();
45
- // Blocks if channel is full - natural backpressure
46
- tx.send(msg).await.unwrap();
47
- }
48
- });
49
-
50
- tokio::spawn(async move {
51
- while let Some(msg) = rx.recv().await {
52
- slow_process(msg).await;
53
- }
54
- });
55
- // Memory usage capped at ~100 messages
56
- ```
57
-
58
- ## Choosing Buffer Size
59
-
60
- ```rust
61
- // Too small: frequent blocking, reduced throughput
62
- let (tx, rx) = mpsc::channel::<Item>(1);
63
-
64
- // Too large: delayed backpressure, memory waste
65
- let (tx, rx) = mpsc::channel::<Item>(1_000_000);
66
-
67
- // Guidelines:
68
- // - Start with expected burst size
69
- // - Measure actual usage in production
70
- // - Err on the smaller side initially
71
-
72
- // Small items, high throughput
73
- let (tx, rx) = mpsc::channel::<u64>(1000);
74
-
75
- // Large items, moderate throughput
76
- let (tx, rx) = mpsc::channel::<LargeStruct>(100);
77
-
78
- // Low latency requirement
79
- let (tx, rx) = mpsc::channel::<Command>(10);
80
- ```
81
-
82
- ## Handling Full Channel
83
-
84
- ```rust
85
- use tokio::sync::mpsc;
86
- use tokio::time::{timeout, Duration};
87
-
88
- let (tx, mut rx) = mpsc::channel::<Message>(100);
89
-
90
- // Option 1: Wait indefinitely (default)
91
- tx.send(msg).await?;
92
-
93
- // Option 2: Try send, fail if full
94
- match tx.try_send(msg) {
95
- Ok(()) => println!("Sent"),
96
- Err(TrySendError::Full(msg)) => {
97
- println!("Channel full, dropping message");
98
- }
99
- Err(TrySendError::Closed(msg)) => {
100
- println!("Receiver dropped");
101
- }
102
- }
103
-
104
- // Option 3: Timeout
105
- match timeout(Duration::from_secs(1), tx.send(msg)).await {
106
- Ok(Ok(())) => println!("Sent"),
107
- Ok(Err(_)) => println!("Channel closed"),
108
- Err(_) => println!("Timeout - channel full for too long"),
109
- }
110
-
111
- // Option 4: send with permit reservation
112
- let permit = tx.reserve().await?;
113
- permit.send(msg); // Guaranteed to succeed
114
- ```
115
-
116
- ## Channel Types
117
-
118
- ```rust
119
- // mpsc: many producers, single consumer
120
- let (tx, rx) = mpsc::channel::<Message>(100);
121
- let tx2 = tx.clone(); // Can clone sender
122
-
123
- // oneshot: single value, one producer, one consumer
124
- let (tx, rx) = oneshot::channel::<Response>();
125
- tx.send(response); // Can only send once
126
-
127
- // broadcast: multiple consumers, each gets all messages
128
- let (tx, _) = broadcast::channel::<Event>(100);
129
- let mut rx1 = tx.subscribe();
130
- let mut rx2 = tx.subscribe();
131
-
132
- // watch: single latest value, multiple consumers
133
- let (tx, rx) = watch::channel::<State>(initial);
134
- // Receivers see latest value, not all values
135
- ```
136
-
137
- ## Worker Pool Pattern
138
-
139
- ```rust
140
- async fn process_with_workers(items: Vec<Item>) -> Vec<Result> {
141
- let (tx, rx) = mpsc::channel(100);
142
- let rx = Arc::new(Mutex::new(rx));
143
-
144
- // Spawn worker pool
145
- let workers: Vec<_> = (0..4).map(|_| {
146
- let rx = rx.clone();
147
- tokio::spawn(async move {
148
- loop {
149
- let item = {
150
- let mut rx = rx.lock().await;
151
- rx.recv().await
152
- };
153
- match item {
154
- Some(item) => process(item).await,
155
- None => break,
156
- }
157
- }
158
- })
159
- }).collect();
160
-
161
- // Send items
162
- for item in items {
163
- tx.send(item).await.unwrap();
164
- }
165
- drop(tx); // Signal workers to stop
166
-
167
- futures::future::join_all(workers).await;
168
- }
169
- ```
170
-
171
- ## See Also
172
-
173
- - [async-mpsc-queue](./async-mpsc-queue.md) - Multi-producer patterns
174
- - [async-oneshot-response](./async-oneshot-response.md) - Request-response pattern
175
- - [async-watch-latest](./async-watch-latest.md) - Latest-value broadcasting