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,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