agy-superpowers 5.2.2 → 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 (220) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/scratch-scripts.md +37 -0
  4. package/template/agent/rules/superpowers.md +4 -51
  5. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  6. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  7. package/template/agent/skills/api-design/SKILL.md +0 -193
  8. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  9. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  10. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  11. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  12. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  13. package/template/agent/skills/community-manager/SKILL.md +0 -115
  14. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  15. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  16. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  17. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  18. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  19. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  20. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  21. package/template/agent/skills/game-design/SKILL.md +0 -194
  22. package/template/agent/skills/game-developer/SKILL.md +0 -175
  23. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  24. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  25. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  26. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  27. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  28. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  29. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  30. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  31. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  32. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  33. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  34. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  35. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  36. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  37. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  38. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  39. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  40. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  41. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  42. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  43. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  44. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  45. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  46. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  47. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  48. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  53. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  54. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  55. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  56. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  57. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  58. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  59. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  60. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  61. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  62. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  63. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  68. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  69. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  70. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  71. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  72. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  73. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  74. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  75. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  76. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  77. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  78. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  83. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  84. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  85. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  86. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  87. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  88. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  89. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  90. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  91. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  92. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  93. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  94. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  95. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  96. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  97. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  98. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  99. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  100. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  101. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  102. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  103. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  104. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  106. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  107. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  108. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  109. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  110. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  111. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  113. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  114. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  115. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  116. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  117. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  118. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  119. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  120. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  121. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  122. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  123. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  124. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  125. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  126. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  127. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  132. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  133. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  134. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  135. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  136. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  137. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  138. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  139. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  140. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  141. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  148. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  149. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  150. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  151. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  152. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  153. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  154. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  155. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  156. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  157. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  158. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  160. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  161. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  162. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  163. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  164. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  165. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  166. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  167. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  168. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  169. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  170. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  172. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  173. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  174. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  175. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  176. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  177. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  179. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  180. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  181. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  182. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  183. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  184. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  185. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  186. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  187. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  188. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  189. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  190. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  191. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  192. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  193. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  194. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  195. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  196. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  197. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  198. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  199. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  200. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  201. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  202. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  203. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  204. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  207. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  208. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  210. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  211. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  212. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  213. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  214. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  215. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  216. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  217. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  218. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  219. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  220. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,143 +0,0 @@
1
- # api-builder-must-use
2
-
3
- > Mark builder methods with `#[must_use]` to prevent silent drops
4
-
5
- ## Why It Matters
6
-
7
- Builder pattern methods return a modified builder. Without `#[must_use]`, calling a builder method and ignoring the return value silently does nothing—the builder is dropped, and the configuration is lost. This creates confusing bugs where code appears correct but has no effect.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct RequestBuilder {
13
- url: String,
14
- timeout: Option<Duration>,
15
- headers: Vec<(String, String)>,
16
- }
17
-
18
- impl RequestBuilder {
19
- fn timeout(mut self, duration: Duration) -> Self {
20
- self.timeout = Some(duration);
21
- self
22
- }
23
-
24
- fn header(mut self, key: &str, value: &str) -> Self {
25
- self.headers.push((key.to_string(), value.to_string()));
26
- self
27
- }
28
- }
29
-
30
- // Bug: builder methods are ignored - no warning!
31
- let request = RequestBuilder::new("https://api.example.com");
32
- request.timeout(Duration::from_secs(30)); // Dropped silently!
33
- request.header("Authorization", "Bearer token"); // Dropped silently!
34
- let response = request.send(); // Sends with no timeout or headers
35
- ```
36
-
37
- ## Good
38
-
39
- ```rust
40
- struct RequestBuilder {
41
- url: String,
42
- timeout: Option<Duration>,
43
- headers: Vec<(String, String)>,
44
- }
45
-
46
- impl RequestBuilder {
47
- #[must_use = "builder methods return modified builder - chain or assign"]
48
- fn timeout(mut self, duration: Duration) -> Self {
49
- self.timeout = Some(duration);
50
- self
51
- }
52
-
53
- #[must_use = "builder methods return modified builder - chain or assign"]
54
- fn header(mut self, key: &str, value: &str) -> Self {
55
- self.headers.push((key.to_string(), value.to_string()));
56
- self
57
- }
58
- }
59
-
60
- // Now warns: unused return value that must be used
61
- let request = RequestBuilder::new("https://api.example.com");
62
- request.timeout(Duration::from_secs(30)); // Warning!
63
-
64
- // Correct: chain methods
65
- let response = RequestBuilder::new("https://api.example.com")
66
- .timeout(Duration::from_secs(30))
67
- .header("Authorization", "Bearer token")
68
- .send();
69
- ```
70
-
71
- ## Apply to Entire Type
72
-
73
- ```rust
74
- #[must_use = "builders do nothing unless consumed"]
75
- struct ConfigBuilder {
76
- log_level: Level,
77
- max_connections: usize,
78
- }
79
-
80
- // Now all methods returning Self warn if ignored
81
- impl ConfigBuilder {
82
- fn log_level(mut self, level: Level) -> Self {
83
- self.log_level = level;
84
- self
85
- }
86
-
87
- fn max_connections(mut self, n: usize) -> Self {
88
- self.max_connections = n;
89
- self
90
- }
91
-
92
- fn build(self) -> Config {
93
- Config {
94
- log_level: self.log_level,
95
- max_connections: self.max_connections,
96
- }
97
- }
98
- }
99
- ```
100
-
101
- ## Message Guidelines
102
-
103
- ```rust
104
- // Descriptive message helps users understand
105
- #[must_use = "builder methods return modified builder"]
106
- fn with_foo(self, foo: Foo) -> Self { ... }
107
-
108
- #[must_use = "this creates a new String and does not modify the original"]
109
- fn to_uppercase(&self) -> String { ... }
110
-
111
- #[must_use = "iterator adaptors are lazy - use .collect() to consume"]
112
- fn map<F>(self, f: F) -> Map<Self, F> { ... }
113
- ```
114
-
115
- ## Clippy Lint
116
-
117
- ```toml
118
- [lints.clippy]
119
- must_use_candidate = "warn" # Suggests where #[must_use] would help
120
- return_self_not_must_use = "warn" # Specifically for -> Self methods
121
- ```
122
-
123
- ## Standard Library Examples
124
-
125
- ```rust
126
- // std::Option - must_use on map, and, or
127
- let x: Option<i32> = Some(5);
128
- x.map(|v| v * 2); // Warning: unused return value
129
-
130
- // std::Result - must_use on the type itself
131
- #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
132
- pub enum Result<T, E> { ... }
133
-
134
- // Iterator adaptors
135
- let v = vec![1, 2, 3];
136
- v.iter().map(|x| x * 2); // Warning: iterators are lazy
137
- ```
138
-
139
- ## See Also
140
-
141
- - [api-builder-pattern](./api-builder-pattern.md) - Builder pattern best practices
142
- - [api-must-use](./api-must-use.md) - General must_use guidelines
143
- - [err-result-over-panic](./err-result-over-panic.md) - Result types are must_use
@@ -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