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,187 +0,0 @@
1
- # api-builder-pattern
2
-
3
- > Use Builder pattern for complex construction
4
-
5
- ## Why It Matters
6
-
7
- When a type has many optional parameters or complex initialization, the Builder pattern provides a clear, flexible API. It avoids constructors with many parameters (which are error-prone) and makes the code self-documenting.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Constructor with many parameters - hard to read, easy to get wrong
13
- let client = Client::new(
14
- "https://api.example.com", // Which is which?
15
- 30, // Timeout? Retries?
16
- true, // What does this mean?
17
- None,
18
- Some("auth_token"),
19
- false,
20
- );
21
-
22
- // Or many Option fields
23
- struct Client {
24
- url: String,
25
- timeout: Option<Duration>,
26
- retries: Option<u32>,
27
- // ... 10 more optional fields
28
- }
29
- ```
30
-
31
- ## Good
32
-
33
- ```rust
34
- #[derive(Default)]
35
- #[must_use = "builders do nothing unless you call build()"]
36
- pub struct ClientBuilder {
37
- base_url: Option<String>,
38
- timeout: Option<Duration>,
39
- max_retries: u32,
40
- auth_token: Option<String>,
41
- }
42
-
43
- impl ClientBuilder {
44
- pub fn new() -> Self {
45
- Self::default()
46
- }
47
-
48
- /// Sets the base URL for all requests.
49
- pub fn base_url(mut self, url: impl Into<String>) -> Self {
50
- self.base_url = Some(url.into());
51
- self
52
- }
53
-
54
- /// Sets the request timeout. Default is 30 seconds.
55
- pub fn timeout(mut self, timeout: Duration) -> Self {
56
- self.timeout = Some(timeout);
57
- self
58
- }
59
-
60
- /// Sets the maximum number of retries. Default is 3.
61
- pub fn max_retries(mut self, n: u32) -> Self {
62
- self.max_retries = n;
63
- self
64
- }
65
-
66
- /// Sets the authentication token.
67
- pub fn auth_token(mut self, token: impl Into<String>) -> Self {
68
- self.auth_token = Some(token.into());
69
- self
70
- }
71
-
72
- /// Builds the client with the configured options.
73
- pub fn build(self) -> Result<Client, BuilderError> {
74
- let base_url = self.base_url
75
- .ok_or(BuilderError::MissingBaseUrl)?;
76
-
77
- Ok(Client {
78
- base_url,
79
- timeout: self.timeout.unwrap_or(Duration::from_secs(30)),
80
- max_retries: self.max_retries,
81
- auth_token: self.auth_token,
82
- })
83
- }
84
- }
85
-
86
- // Usage - clear and self-documenting
87
- let client = ClientBuilder::new()
88
- .base_url("https://api.example.com")
89
- .timeout(Duration::from_secs(10))
90
- .max_retries(5)
91
- .auth_token("secret")
92
- .build()?;
93
- ```
94
-
95
- ## Builder Variations
96
-
97
- ```rust
98
- // 1. Infallible builder (build() returns T, not Result)
99
- impl WidgetBuilder {
100
- pub fn build(self) -> Widget {
101
- Widget {
102
- color: self.color.unwrap_or(Color::Black),
103
- size: self.size.unwrap_or(Size::Medium),
104
- }
105
- }
106
- }
107
-
108
- // 2. Typestate builder (compile-time required field checking)
109
- pub struct ClientBuilder<Url> {
110
- url: Url,
111
- timeout: Option<Duration>,
112
- }
113
-
114
- pub struct NoUrl;
115
- pub struct HasUrl(String);
116
-
117
- impl ClientBuilder<NoUrl> {
118
- pub fn new() -> Self {
119
- Self { url: NoUrl, timeout: None }
120
- }
121
-
122
- pub fn url(self, url: String) -> ClientBuilder<HasUrl> {
123
- ClientBuilder { url: HasUrl(url), timeout: self.timeout }
124
- }
125
- }
126
-
127
- impl ClientBuilder<HasUrl> {
128
- pub fn build(self) -> Client {
129
- // url is guaranteed to be set
130
- Client { url: self.url.0, timeout: self.timeout }
131
- }
132
- }
133
-
134
- // 3. Consuming vs borrowing (consuming is more common)
135
- // Consuming (takes self)
136
- pub fn timeout(mut self, t: Duration) -> Self { ... }
137
-
138
- // Borrowing (takes &mut self, allows reuse)
139
- pub fn timeout(&mut self, t: Duration) -> &mut Self { ... }
140
- ```
141
-
142
- ## Evidence from reqwest
143
-
144
- ```rust
145
- // https://github.com/seanmonstar/reqwest/blob/master/src/async_impl/client.rs
146
-
147
- #[must_use]
148
- pub struct ClientBuilder {
149
- config: Config,
150
- }
151
-
152
- impl ClientBuilder {
153
- pub fn new() -> ClientBuilder {
154
- ClientBuilder {
155
- config: Config::default(),
156
- }
157
- }
158
-
159
- pub fn timeout(mut self, timeout: Duration) -> ClientBuilder {
160
- self.config.timeout = Some(timeout);
161
- self
162
- }
163
-
164
- pub fn build(self) -> Result<Client, Error> {
165
- // Validation and construction
166
- }
167
- }
168
- ```
169
-
170
- ## Key Attributes
171
-
172
- ```rust
173
- #[derive(Default)] // Enables MyBuilder::default()
174
- #[must_use = "builders do nothing unless you call build()"]
175
- pub struct MyBuilder { ... }
176
-
177
- impl MyBuilder {
178
- #[must_use] // Each method should have this
179
- pub fn option(mut self, value: T) -> Self { ... }
180
- }
181
- ```
182
-
183
- ## See Also
184
-
185
- - [api-builder-must-use](api-builder-must-use.md) - Add #[must_use] to builders
186
- - [api-typestate](api-typestate.md) - Compile-time state machines
187
- - [api-impl-into](api-impl-into.md) - Accept impl Into for flexibility
@@ -1,165 +0,0 @@
1
- # api-common-traits
2
-
3
- > Implement standard traits (Debug, Clone, PartialEq, etc.) for public types
4
-
5
- ## Why It Matters
6
-
7
- Standard traits make your types interoperable with the Rust ecosystem. `Debug` enables `println!("{:?}")` and error messages. `Clone` allows explicit duplication. `PartialEq` enables `==`. Without these, users can't use your types in common patterns like testing, collections, or debugging.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Bare struct - severely limited usability
13
- pub struct Point {
14
- pub x: f64,
15
- pub y: f64,
16
- }
17
-
18
- // Can't debug
19
- println!("{:?}", point); // Error: Debug not implemented
20
-
21
- // Can't compare
22
- if point1 == point2 { } // Error: PartialEq not implemented
23
-
24
- // Can't use in HashMap
25
- let mut map: HashMap<Point, Value> = HashMap::new(); // Error: Hash not implemented
26
-
27
- // Can't clone
28
- let copy = point.clone(); // Error: Clone not implemented
29
- ```
30
-
31
- ## Good
32
-
33
- ```rust
34
- #[derive(Debug, Clone, Copy, PartialEq)]
35
- pub struct Point {
36
- pub x: f64,
37
- pub y: f64,
38
- }
39
-
40
- // Now everything works
41
- println!("{:?}", point);
42
- assert_eq!(point1, point2);
43
- let copy = point; // Copy, not just Clone
44
-
45
- // For hashable types
46
- #[derive(Debug, Clone, PartialEq, Eq, Hash)]
47
- pub struct UserId(u64);
48
-
49
- let mut map: HashMap<UserId, User> = HashMap::new();
50
- ```
51
-
52
- ## Trait Derivation Guide
53
-
54
- | Trait | Derive When | Requirements |
55
- |-------|-------------|--------------|
56
- | `Debug` | Always for public types | All fields implement Debug |
57
- | `Clone` | Type can be duplicated | All fields implement Clone |
58
- | `Copy` | Small, simple types | All fields implement Copy, no Drop |
59
- | `PartialEq` | Comparison makes sense | All fields implement PartialEq |
60
- | `Eq` | Total equality | PartialEq, no floating-point fields |
61
- | `Hash` | Used as HashMap/HashSet key | Eq, consistent with PartialEq |
62
- | `Default` | Sensible default exists | All fields implement Default |
63
- | `PartialOrd` | Ordering makes sense | PartialEq, all fields implement PartialOrd |
64
- | `Ord` | Total ordering | Eq + PartialOrd, no floating-point |
65
-
66
- ## Common Trait Bundles
67
-
68
- ```rust
69
- // ID types
70
- #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
71
- pub struct EntityId(u64);
72
-
73
- // Value types
74
- #[derive(Debug, Clone, Copy, PartialEq, Default)]
75
- pub struct Vector2 { x: f32, y: f32 }
76
-
77
- // Configuration
78
- #[derive(Debug, Clone, PartialEq, Default)]
79
- pub struct Config {
80
- name: String,
81
- options: HashMap<String, String>,
82
- }
83
-
84
- // Error types
85
- #[derive(Debug, Clone, PartialEq, Eq)]
86
- pub enum ParseError {
87
- InvalidSyntax(String),
88
- UnexpectedToken(Token),
89
- }
90
- ```
91
-
92
- ## Manual Implementations
93
-
94
- ```rust
95
- // When derive doesn't do what you want
96
- struct CaseInsensitiveString(String);
97
-
98
- impl PartialEq for CaseInsensitiveString {
99
- fn eq(&self, other: &Self) -> bool {
100
- self.0.to_lowercase() == other.0.to_lowercase()
101
- }
102
- }
103
-
104
- impl Eq for CaseInsensitiveString {}
105
-
106
- impl Hash for CaseInsensitiveString {
107
- fn hash<H: Hasher>(&self, state: &mut H) {
108
- // Must be consistent with PartialEq
109
- self.0.to_lowercase().hash(state);
110
- }
111
- }
112
-
113
- // Custom Debug for sensitive data
114
- struct Password(String);
115
-
116
- impl Debug for Password {
117
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118
- write!(f, "Password([REDACTED])")
119
- }
120
- }
121
- ```
122
-
123
- ## Serde Traits
124
-
125
- ```rust
126
- use serde::{Serialize, Deserialize};
127
-
128
- // For serializable types
129
- #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
130
- pub struct ApiResponse {
131
- pub status: String,
132
- pub data: Vec<Item>,
133
- }
134
-
135
- // With custom serialization
136
- #[derive(Debug, Clone, Serialize, Deserialize)]
137
- pub struct Config {
138
- #[serde(default)]
139
- pub verbose: bool,
140
-
141
- #[serde(skip_serializing_if = "Option::is_none")]
142
- pub api_key: Option<String>,
143
- }
144
- ```
145
-
146
- ## Minimum Recommended
147
-
148
- ```rust
149
- // At minimum, public types should have:
150
- #[derive(Debug, Clone, PartialEq)]
151
- pub struct MyType { ... }
152
-
153
- // Add based on use case:
154
- // + Eq, Hash → for HashMap keys
155
- // + Ord, PartialOrd → for BTreeMap, sorting
156
- // + Default → for Option::unwrap_or_default()
157
- // + Copy → for small value types
158
- // + Serialize → for serialization
159
- ```
160
-
161
- ## See Also
162
-
163
- - [own-copy-small](./own-copy-small.md) - When to implement Copy
164
- - [api-default-impl](./api-default-impl.md) - Implementing Default
165
- - [doc-examples-section](./doc-examples-section.md) - Documenting trait implementations
@@ -1,177 +0,0 @@
1
- # api-default-impl
2
-
3
- > Implement `Default` for types with sensible default values
4
-
5
- ## Why It Matters
6
-
7
- `Default` is a standard trait that provides a canonical way to create a default instance. It integrates with many ecosystem patterns: `Option::unwrap_or_default()`, `#[derive(Default)]`, struct update syntax `..Default::default()`, and generic code that requires `T: Default`. Implementing it makes your types more ergonomic.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct Config {
13
- timeout: Duration,
14
- retries: u32,
15
- verbose: bool,
16
- }
17
-
18
- impl Config {
19
- // Custom constructor - works but non-standard
20
- fn new() -> Self {
21
- Config {
22
- timeout: Duration::from_secs(30),
23
- retries: 3,
24
- verbose: false,
25
- }
26
- }
27
- }
28
-
29
- // Can't use with standard patterns
30
- let config: Config = Default::default(); // Error: Default not implemented
31
- let timeout = settings.get("timeout").unwrap_or_default(); // Won't work
32
- ```
33
-
34
- ## Good
35
-
36
- ```rust
37
- #[derive(Default)]
38
- struct Config {
39
- #[default = Duration::from_secs(30)] // Nightly, or implement manually
40
- timeout: Duration,
41
- retries: u32, // Defaults to 0 with derive
42
- verbose: bool, // Defaults to false with derive
43
- }
44
-
45
- // Or implement manually for custom defaults
46
- impl Default for Config {
47
- fn default() -> Self {
48
- Config {
49
- timeout: Duration::from_secs(30),
50
- retries: 3,
51
- verbose: false,
52
- }
53
- }
54
- }
55
-
56
- // Now works with all standard patterns
57
- let config = Config::default();
58
- let config = Config { retries: 5, ..Default::default() };
59
- let value = map.get("key").cloned().unwrap_or_default();
60
- ```
61
-
62
- ## Derive vs Manual
63
-
64
- ```rust
65
- // Derive: all fields use their own Default
66
- #[derive(Default)]
67
- struct Simple {
68
- count: u32, // 0
69
- name: String, // ""
70
- items: Vec<i32>, // []
71
- }
72
-
73
- // Manual: when you need custom defaults
74
- struct Connection {
75
- host: String,
76
- port: u16,
77
- timeout: Duration,
78
- }
79
-
80
- impl Default for Connection {
81
- fn default() -> Self {
82
- Connection {
83
- host: "localhost".to_string(),
84
- port: 8080,
85
- timeout: Duration::from_secs(30),
86
- }
87
- }
88
- }
89
- ```
90
-
91
- ## Builder with Default
92
-
93
- ```rust
94
- #[derive(Default)]
95
- struct ServerBuilder {
96
- host: String,
97
- port: u16,
98
- workers: usize,
99
- }
100
-
101
- impl ServerBuilder {
102
- fn host(mut self, host: impl Into<String>) -> Self {
103
- self.host = host.into();
104
- self
105
- }
106
-
107
- fn port(mut self, port: u16) -> Self {
108
- self.port = port;
109
- self
110
- }
111
- }
112
-
113
- // Clean initialization
114
- let server = ServerBuilder::default()
115
- .host("0.0.0.0")
116
- .port(3000)
117
- .build();
118
- ```
119
-
120
- ## Default with Required Fields
121
-
122
- ```rust
123
- // When some fields have no sensible default, don't implement Default
124
- struct User {
125
- id: UserId, // No sensible default
126
- name: String, // Could default to ""
127
- }
128
-
129
- // Instead, provide a constructor
130
- impl User {
131
- fn new(id: UserId, name: impl Into<String>) -> Self {
132
- User { id, name: name.into() }
133
- }
134
- }
135
-
136
- // Or use builder with required fields
137
- struct UserBuilder {
138
- id: Option<UserId>,
139
- name: String,
140
- }
141
-
142
- impl Default for UserBuilder {
143
- fn default() -> Self {
144
- UserBuilder {
145
- id: None,
146
- name: String::new(),
147
- }
148
- }
149
- }
150
- ```
151
-
152
- ## Generic Default
153
-
154
- ```rust
155
- // Require Default in generic bounds when needed
156
- fn create_or_default<T: Default>(opt: Option<T>) -> T {
157
- opt.unwrap_or_default()
158
- }
159
-
160
- // PhantomData is Default regardless of T
161
- use std::marker::PhantomData;
162
- struct Wrapper<T> {
163
- _marker: PhantomData<T>,
164
- }
165
-
166
- impl<T> Default for Wrapper<T> {
167
- fn default() -> Self {
168
- Wrapper { _marker: PhantomData }
169
- }
170
- }
171
- ```
172
-
173
- ## See Also
174
-
175
- - [api-builder-pattern](./api-builder-pattern.md) - Building complex types
176
- - [api-common-traits](./api-common-traits.md) - Other common traits to implement
177
- - [api-from-not-into](./api-from-not-into.md) - Conversion traits
@@ -1,163 +0,0 @@
1
- # api-extension-trait
2
-
3
- > Use extension traits to add methods to external types
4
-
5
- ## Why It Matters
6
-
7
- Rust's orphan rules prevent implementing external traits on external types. Extension traits provide a workaround: define a new trait with your methods, then implement it for the external type. This pattern is used extensively in the ecosystem (e.g., `itertools::Itertools`, `tokio::AsyncReadExt`).
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Can't add methods directly to external types
13
- impl Vec<u8> {
14
- fn as_hex(&self) -> String {
15
- // Error: cannot define inherent impl for a type outside this crate
16
- }
17
- }
18
-
19
- // Can't implement external trait for external type
20
- impl SomeExternalTrait for Vec<u8> {
21
- // Error: orphan rules violation
22
- }
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- // Define an extension trait
29
- pub trait ByteSliceExt {
30
- fn as_hex(&self) -> String;
31
- fn is_ascii_printable(&self) -> bool;
32
- }
33
-
34
- // Implement for the external type
35
- impl ByteSliceExt for [u8] {
36
- fn as_hex(&self) -> String {
37
- self.iter()
38
- .map(|b| format!("{:02x}", b))
39
- .collect()
40
- }
41
-
42
- fn is_ascii_printable(&self) -> bool {
43
- self.iter().all(|b| b.is_ascii_graphic() || b.is_ascii_whitespace())
44
- }
45
- }
46
-
47
- // Usage: import the trait to use the methods
48
- use my_crate::ByteSliceExt;
49
-
50
- let data: &[u8] = b"hello";
51
- println!("{}", data.as_hex()); // "68656c6c6f"
52
- ```
53
-
54
- ## Convention: Ext Suffix
55
-
56
- ```rust
57
- // Standard naming: TypeExt for extending Type
58
- pub trait OptionExt<T> {
59
- fn unwrap_or_log(self, msg: &str) -> Option<T>;
60
- }
61
-
62
- impl<T> OptionExt<T> for Option<T> {
63
- fn unwrap_or_log(self, msg: &str) -> Option<T> {
64
- if self.is_none() {
65
- log::warn!("{}", msg);
66
- }
67
- self
68
- }
69
- }
70
-
71
- // For generic extensions
72
- pub trait ResultExt<T, E> {
73
- fn log_err(self) -> Self;
74
- }
75
-
76
- impl<T, E: std::fmt::Display> ResultExt<T, E> for Result<T, E> {
77
- fn log_err(self) -> Self {
78
- if let Err(ref e) = self {
79
- log::error!("{}", e);
80
- }
81
- self
82
- }
83
- }
84
- ```
85
-
86
- ## Ecosystem Examples
87
-
88
- ```rust
89
- // itertools::Itertools
90
- use itertools::Itertools;
91
- let groups = vec![1, 1, 2, 2, 3].into_iter().group_by(|x| *x);
92
-
93
- // futures::StreamExt
94
- use futures::StreamExt;
95
- let next = stream.next().await;
96
-
97
- // tokio::io::AsyncReadExt
98
- use tokio::io::AsyncReadExt;
99
- let mut buf = [0u8; 1024];
100
- reader.read(&mut buf).await?;
101
-
102
- // anyhow::Context
103
- use anyhow::Context;
104
- let content = std::fs::read_to_string(path)
105
- .with_context(|| format!("failed to read {}", path))?;
106
- ```
107
-
108
- ## Scoped Extensions
109
-
110
- ```rust
111
- // Extension only visible where imported
112
- mod string_utils {
113
- pub trait StringExt {
114
- fn truncate_ellipsis(&self, max_len: usize) -> String;
115
- }
116
-
117
- impl StringExt for str {
118
- fn truncate_ellipsis(&self, max_len: usize) -> String {
119
- if self.len() <= max_len {
120
- self.to_string()
121
- } else {
122
- format!("{}...", &self[..max_len.saturating_sub(3)])
123
- }
124
- }
125
- }
126
- }
127
-
128
- // Only available when explicitly imported
129
- use string_utils::StringExt;
130
- let short = "very long string".truncate_ellipsis(10);
131
- ```
132
-
133
- ## Generic Extensions with Bounds
134
-
135
- ```rust
136
- pub trait VecExt<T> {
137
- fn push_if_unique(&mut self, item: T)
138
- where
139
- T: PartialEq;
140
- }
141
-
142
- impl<T> VecExt<T> for Vec<T> {
143
- fn push_if_unique(&mut self, item: T)
144
- where
145
- T: PartialEq,
146
- {
147
- if !self.contains(&item) {
148
- self.push(item);
149
- }
150
- }
151
- }
152
-
153
- // Works with any T: PartialEq
154
- let mut v = vec![1, 2, 3];
155
- v.push_if_unique(2); // No-op
156
- v.push_if_unique(4); // Adds 4
157
- ```
158
-
159
- ## See Also
160
-
161
- - [api-sealed-trait](./api-sealed-trait.md) - Controlling trait implementations
162
- - [api-impl-into](./api-impl-into.md) - Using standard conversion traits
163
- - [name-as-free](./name-as-free.md) - Naming conventions for conversions