agy-superpowers 5.2.1 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/patches/skills-patches.md +23 -0
  4. package/template/agent/rules/scratch-scripts.md +37 -0
  5. package/template/agent/rules/superpowers.md +6 -50
  6. package/template/agent/skills/brainstorming/SKILL.md +4 -3
  7. package/template/agent/skills/brainstorming/visual-companion.md +2 -3
  8. package/template/agent/skills/finishing-a-development-branch/SKILL.md +11 -16
  9. package/template/agent/skills/subagent-driven-development/SKILL.md +16 -0
  10. package/template/agent/skills/subagent-driven-development/implementer-prompt.md +4 -3
  11. package/template/agent/skills/using-git-worktrees/SKILL.md +3 -2
  12. package/template/agent/skills/using-superpowers/SKILL.md +8 -6
  13. package/template/agent/skills/using-superpowers/references/copilot-tools.md +52 -0
  14. package/template/agent/skills/writing-plans/SKILL.md +5 -3
  15. package/template/agent/skills/writing-skills/SKILL.md +1 -1
  16. package/template/agent/superpowers-version.json +2 -2
  17. package/template/agent/tmp/agent-config-backup.yml +9 -0
  18. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  19. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  20. package/template/agent/skills/api-design/SKILL.md +0 -193
  21. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  22. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  23. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  24. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  25. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  26. package/template/agent/skills/community-manager/SKILL.md +0 -115
  27. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  28. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  29. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  30. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  31. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  32. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  33. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  34. package/template/agent/skills/game-design/SKILL.md +0 -194
  35. package/template/agent/skills/game-developer/SKILL.md +0 -175
  36. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  37. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  38. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  39. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  40. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  41. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  42. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  43. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  44. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  45. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  46. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  47. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  48. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  49. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  50. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  64. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  79. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  80. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  94. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  95. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  105. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  106. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  117. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  118. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  128. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  129. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  143. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  144. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  159. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  160. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  171. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  172. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  183. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  184. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  194. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  195. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  206. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  218. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  228. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  229. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  230. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  231. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  232. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  233. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,146 +0,0 @@
1
- # api-from-not-into
2
-
3
- > Implement `From<T>`, not `Into<U>` - From gives you Into for free
4
-
5
- ## Why It Matters
6
-
7
- The standard library has a blanket implementation: `impl<T, U> Into<U> for T where U: From<T>`. This means implementing `From<T> for U` automatically gives you `Into<U> for T`. Implementing `Into` directly bypasses this and is considered non-idiomatic. Always implement `From`.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct UserId(u64);
13
-
14
- // Non-idiomatic: implementing Into directly
15
- impl Into<UserId> for u64 {
16
- fn into(self) -> UserId {
17
- UserId(self)
18
- }
19
- }
20
-
21
- // Works, but now you can't use From syntax
22
- let id = UserId::from(42); // Error: From not implemented
23
- let id: UserId = 42.into(); // Works, but limited
24
- ```
25
-
26
- ## Good
27
-
28
- ```rust
29
- struct UserId(u64);
30
-
31
- // Idiomatic: implement From
32
- impl From<u64> for UserId {
33
- fn from(id: u64) -> Self {
34
- UserId(id)
35
- }
36
- }
37
-
38
- // Now both work automatically
39
- let id = UserId::from(42); // From syntax
40
- let id: UserId = 42.into(); // Into syntax (via blanket impl)
41
-
42
- // And Into bound works in generics
43
- fn process(id: impl Into<UserId>) {
44
- let id: UserId = id.into();
45
- }
46
- process(42u64); // Works!
47
- ```
48
-
49
- ## Blanket Implementation
50
-
51
- ```rust
52
- // This is in std, you don't write it
53
- impl<T, U> Into<U> for T
54
- where
55
- U: From<T>,
56
- {
57
- fn into(self) -> U {
58
- U::from(self)
59
- }
60
- }
61
-
62
- // So when you implement From:
63
- impl From<String> for MyType { ... }
64
-
65
- // You automatically get:
66
- // impl Into<MyType> for String { ... }
67
- ```
68
-
69
- ## Multiple From Implementations
70
-
71
- ```rust
72
- struct Email(String);
73
-
74
- impl From<String> for Email {
75
- fn from(s: String) -> Self {
76
- Email(s)
77
- }
78
- }
79
-
80
- impl From<&str> for Email {
81
- fn from(s: &str) -> Self {
82
- Email(s.to_string())
83
- }
84
- }
85
-
86
- // All of these work
87
- let e1 = Email::from("test@example.com");
88
- let e2 = Email::from(String::from("test@example.com"));
89
- let e3: Email = "test@example.com".into();
90
- let e4: Email = String::from("test@example.com").into();
91
- ```
92
-
93
- ## TryFrom for Fallible Conversions
94
-
95
- ```rust
96
- use std::convert::TryFrom;
97
-
98
- struct PositiveInt(u32);
99
-
100
- // Fallible conversion
101
- impl TryFrom<i32> for PositiveInt {
102
- type Error = &'static str;
103
-
104
- fn try_from(value: i32) -> Result<Self, Self::Error> {
105
- if value > 0 {
106
- Ok(PositiveInt(value as u32))
107
- } else {
108
- Err("value must be positive")
109
- }
110
- }
111
- }
112
-
113
- // Usage
114
- let pos = PositiveInt::try_from(42)?; // From-style
115
- let pos: PositiveInt = 42.try_into()?; // Into-style (via blanket)
116
- ```
117
-
118
- ## Clippy Lint
119
-
120
- ```toml
121
- [lints.clippy]
122
- from_over_into = "warn" # Warns when implementing Into instead of From
123
- ```
124
-
125
- ```rust
126
- // Clippy will warn:
127
- impl Into<Bar> for Foo { // Warning: prefer From
128
- fn into(self) -> Bar { ... }
129
- }
130
- ```
131
-
132
- ## When Into IS Needed (Rare)
133
-
134
- ```rust
135
- // Only when implementing for external types in specific trait bounds
136
- // This is very rare and usually indicates a design issue
137
-
138
- // Example: you can't implement From<ExternalA> for ExternalB
139
- // because of orphan rules. But you usually shouldn't need to.
140
- ```
141
-
142
- ## See Also
143
-
144
- - [api-impl-into](./api-impl-into.md) - Using Into in function parameters
145
- - [err-from-impl](./err-from-impl.md) - From for error types
146
- - [api-newtype-safety](./api-newtype-safety.md) - Newtype conversions
@@ -1,142 +0,0 @@
1
- # api-impl-asref
2
-
3
- > Use `AsRef<T>` when you only need to borrow the inner data
4
-
5
- ## Why It Matters
6
-
7
- `AsRef<T>` provides a cheap borrowed view of data without taking ownership or copying. Functions accepting `impl AsRef<T>` can work with multiple types that contain or represent `T`, making APIs flexible while avoiding unnecessary allocations. Use `AsRef` when you only need to read, `Into` when you need to own.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Forces callers to provide exact types
13
- fn process_text(text: &str) { ... }
14
- fn read_file(path: &Path) { ... }
15
-
16
- // Can't call directly with owned types
17
- let s = String::from("hello");
18
- process_text(&s); // Works but verbose
19
-
20
- let p = PathBuf::from("/file");
21
- read_file(&p); // Works but verbose
22
- read_file("/file"); // Error! &str != &Path
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- // Accept anything that can be viewed as the target type
29
- fn process_text(text: impl AsRef<str>) {
30
- let s: &str = text.as_ref();
31
- println!("{}", s);
32
- }
33
-
34
- fn read_file(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
35
- std::fs::read(path.as_ref())
36
- }
37
-
38
- // All of these work:
39
- process_text("literal"); // &str
40
- process_text(String::from("owned")); // String
41
- process_text(Cow::from("cow")); // Cow<str>
42
-
43
- read_file("/path/to/file"); // &str
44
- read_file(Path::new("/path")); // &Path
45
- read_file(PathBuf::from("/path")); // PathBuf
46
- read_file(OsStr::new("/path")); // &OsStr
47
- ```
48
-
49
- ## AsRef vs Into vs Borrow
50
-
51
- ```rust
52
- // AsRef<T>: cheap borrow, no ownership transfer
53
- fn read(p: impl AsRef<Path>) {
54
- let path: &Path = p.as_ref();
55
- }
56
-
57
- // Into<T>: ownership transfer, may allocate
58
- fn store(p: impl Into<PathBuf>) {
59
- let owned: PathBuf = p.into();
60
- }
61
-
62
- // Borrow<T>: like AsRef but with Eq/Hash consistency guarantee
63
- use std::borrow::Borrow;
64
- fn lookup<Q: ?Sized>(map: &HashMap<String, V>, key: &Q) -> Option<&V>
65
- where
66
- String: Borrow<Q>,
67
- Q: Hash + Eq,
68
- {
69
- map.get(key)
70
- }
71
- ```
72
-
73
- ## Implement AsRef for Custom Types
74
-
75
- ```rust
76
- struct Name(String);
77
-
78
- impl AsRef<str> for Name {
79
- fn as_ref(&self) -> &str {
80
- &self.0
81
- }
82
- }
83
-
84
- impl AsRef<[u8]> for Name {
85
- fn as_ref(&self) -> &[u8] {
86
- self.0.as_bytes()
87
- }
88
- }
89
-
90
- // Now Name works with functions expecting AsRef<str>
91
- fn greet(name: impl AsRef<str>) {
92
- println!("Hello, {}!", name.as_ref());
93
- }
94
-
95
- greet(Name("Alice".into()));
96
- ```
97
-
98
- ## Common AsRef Implementations
99
-
100
- ```rust
101
- // Standard library provides many
102
- impl AsRef<str> for String { ... }
103
- impl AsRef<str> for str { ... }
104
- impl AsRef<[u8]> for str { ... }
105
- impl AsRef<[u8]> for String { ... }
106
- impl AsRef<[u8]> for Vec<u8> { ... }
107
- impl AsRef<Path> for str { ... }
108
- impl AsRef<Path> for String { ... }
109
- impl AsRef<Path> for PathBuf { ... }
110
- impl AsRef<Path> for OsStr { ... }
111
- impl AsRef<OsStr> for str { ... }
112
- ```
113
-
114
- ## When to Use Which
115
-
116
- | Trait | Use When |
117
- |-------|----------|
118
- | `&T` | Single type, simple API |
119
- | `AsRef<T>` | Read-only access, multiple input types |
120
- | `Into<T>` | Need to store/own the value |
121
- | `Borrow<T>` | HashMap/HashSet keys, Eq/Hash needed |
122
- | `Deref<Target=T>` | Smart pointer semantics |
123
-
124
- ## Pattern: Optional AsRef Bound
125
-
126
- ```rust
127
- // When T itself might be passed
128
- fn process<T: AsRef<U>, U>(value: T) {
129
- let inner: &U = value.as_ref();
130
- }
131
-
132
- // More flexible: accept T or &T
133
- fn process<T: AsRef<U> + ?Sized, U: ?Sized>(value: &T) {
134
- let inner: &U = value.as_ref();
135
- }
136
- ```
137
-
138
- ## See Also
139
-
140
- - [api-impl-into](./api-impl-into.md) - When to use Into instead
141
- - [own-slice-over-vec](./own-slice-over-vec.md) - Using slices for flexibility
142
- - [own-borrow-over-clone](./own-borrow-over-clone.md) - Preferring borrows
@@ -1,160 +0,0 @@
1
- # api-impl-into
2
-
3
- > Accept `impl Into<T>` for flexible APIs, implement `From<T>` for conversions
4
-
5
- ## Why It Matters
6
-
7
- APIs that accept `impl Into<T>` are ergonomic—callers can pass the target type directly or any type that converts to it. This reduces boilerplate `.into()` calls at call sites. Implement `From<T>` rather than `Into<T>` because `From` implies `Into` through a blanket implementation.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Requires exact type - forces callers to convert
13
- fn process_path(path: PathBuf) { ... }
14
- fn set_name(name: String) { ... }
15
-
16
- // Caller must convert explicitly
17
- process_path(PathBuf::from("/path/to/file"));
18
- process_path("/path/to/file".to_path_buf()); // Verbose
19
- process_path("/path/to/file".into()); // Explicit
20
-
21
- set_name(String::from("Alice"));
22
- set_name("Alice".to_string()); // Verbose
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- // Accept anything that converts to the target type
29
- fn process_path(path: impl Into<PathBuf>) {
30
- let path = path.into(); // Convert once inside
31
- // ...
32
- }
33
-
34
- fn set_name(name: impl Into<String>) {
35
- let name = name.into();
36
- // ...
37
- }
38
-
39
- // Callers are ergonomic
40
- process_path("/path/to/file"); // &str converts automatically
41
- process_path(PathBuf::from(".")); // PathBuf works too
42
-
43
- set_name("Alice"); // &str
44
- set_name(String::from("Alice")); // String
45
- set_name(format!("User-{}", id)); // String from format!
46
- ```
47
-
48
- ## Implement From, Not Into
49
-
50
- ```rust
51
- struct UserId(u64);
52
-
53
- // ✅ Implement From
54
- impl From<u64> for UserId {
55
- fn from(id: u64) -> Self {
56
- UserId(id)
57
- }
58
- }
59
-
60
- // Into is automatically provided by blanket impl
61
- let id: UserId = 42u64.into(); // Works!
62
-
63
- // ❌ Don't implement Into directly
64
- impl Into<UserId> for u64 {
65
- fn into(self) -> UserId {
66
- UserId(self) // This works but is non-idiomatic
67
- }
68
- }
69
- ```
70
-
71
- ## Common Conversions
72
-
73
- ```rust
74
- // String-like types
75
- fn log_message(msg: impl Into<String>) { ... }
76
- log_message("literal"); // &str
77
- log_message(String::from("own")); // String
78
- log_message(Cow::from("cow")); // Cow<str>
79
-
80
- // Path-like types
81
- fn read_file(path: impl AsRef<Path>) { ... } // AsRef for borrowed access
82
- fn write_file(path: impl Into<PathBuf>) { ... } // Into when storing
83
-
84
- // Duration
85
- fn set_timeout(duration: impl Into<Duration>) { ... }
86
- set_timeout(Duration::from_secs(5));
87
- // Note: no blanket impl for integers, would need custom wrapper
88
- ```
89
-
90
- ## AsRef vs Into
91
-
92
- ```rust
93
- // AsRef<T>: borrow as &T, no conversion cost
94
- fn count_bytes(data: impl AsRef<[u8]>) -> usize {
95
- data.as_ref().len() // Just borrows, no allocation
96
- }
97
- count_bytes("hello"); // &str -> &[u8]
98
- count_bytes(b"hello"); // &[u8] -> &[u8]
99
- count_bytes(vec![1, 2, 3]); // &Vec<u8> -> &[u8]
100
-
101
- // Into<T>: convert to owned T, may allocate
102
- fn store_data(data: impl Into<Vec<u8>>) {
103
- let owned: Vec<u8> = data.into(); // Takes ownership
104
- // ...
105
- }
106
- ```
107
-
108
- ## When NOT to Use impl Into
109
-
110
- ```rust
111
- // ❌ Trait objects need Sized
112
- fn process(handler: impl Into<Box<dyn Handler>>) { }
113
- // Better: just take Box<dyn Handler> directly
114
-
115
- // ❌ Recursive types
116
- struct Node {
117
- children: Vec<impl Into<Node>>, // Error: impl Trait not allowed here
118
- }
119
-
120
- // ❌ Performance-critical hot paths (minor overhead of trait dispatch)
121
- fn hot_path(value: impl Into<u64>) {
122
- // Consider taking u64 directly if called billions of times
123
- }
124
-
125
- // ❌ When you need to name the type
126
- fn returns_impl() -> impl Into<String> { } // Opaque, hard to use
127
- ```
128
-
129
- ## Builder Pattern with Into
130
-
131
- ```rust
132
- struct Config {
133
- name: String,
134
- path: PathBuf,
135
- }
136
-
137
- impl Config {
138
- fn new(name: impl Into<String>) -> Self {
139
- Config {
140
- name: name.into(),
141
- path: PathBuf::new(),
142
- }
143
- }
144
-
145
- fn path(mut self, path: impl Into<PathBuf>) -> Self {
146
- self.path = path.into();
147
- self
148
- }
149
- }
150
-
151
- // Clean builder calls
152
- let config = Config::new("myapp")
153
- .path("/etc/myapp");
154
- ```
155
-
156
- ## See Also
157
-
158
- - [api-impl-asref](./api-impl-asref.md) - When to use AsRef instead
159
- - [api-from-not-into](./api-from-not-into.md) - Why From is preferred
160
- - [err-from-impl](./err-from-impl.md) - From for error conversion
@@ -1,125 +0,0 @@
1
- # api-must-use
2
-
3
- > Mark types and functions with `#[must_use]` when ignoring results is likely a bug
4
-
5
- ## Why It Matters
6
-
7
- Some return values should never be ignored—`Result`, locks, RAII guards, computed values that have no side effects. Without `#[must_use]`, silently discarding these values can introduce subtle bugs that are hard to detect. The attribute generates compiler warnings when the value is unused.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Result ignored - error silently dropped
13
- fn send_email(to: &str, body: &str) -> Result<(), EmailError> { ... }
14
-
15
- send_email("user@example.com", "Hello!"); // No warning if Result ignored!
16
- // Email may have failed, but we don't know
17
-
18
- // Computed value ignored - likely a bug
19
- fn compute_checksum(data: &[u8]) -> u32 { ... }
20
-
21
- let data = vec![1, 2, 3, 4];
22
- compute_checksum(&data); // Result discarded - pointless call
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- #[must_use = "this `Result` may be an `Err` that should be handled"]
29
- fn send_email(to: &str, body: &str) -> Result<(), EmailError> { ... }
30
-
31
- send_email("user@example.com", "Hello!");
32
- // Warning: unused `Result` that must be used
33
-
34
- // Mark pure functions
35
- #[must_use = "this returns a new value and does not modify the input"]
36
- fn compute_checksum(data: &[u8]) -> u32 { ... }
37
-
38
- compute_checksum(&data);
39
- // Warning: unused return value of `compute_checksum` that must be used
40
- ```
41
-
42
- ## Apply to Types
43
-
44
- ```rust
45
- // Mark the type itself when it should always be used
46
- #[must_use = "futures do nothing unless polled"]
47
- struct MyFuture<T> { ... }
48
-
49
- // Mark RAII guards
50
- #[must_use = "if unused, the lock will be immediately released"]
51
- struct MutexGuard<'a, T> { ... }
52
-
53
- // Mark results/errors
54
- #[must_use = "errors should be handled"]
55
- enum AppError { ... }
56
- ```
57
-
58
- ## Standard Library Examples
59
-
60
- ```rust
61
- // Result and Option are #[must_use]
62
- let v: Vec<i32> = vec![1, 2, 3];
63
- v.first(); // Warning: unused Option
64
-
65
- // Iterator adapters are #[must_use]
66
- v.iter().map(|x| x * 2); // Warning: iterators are lazy
67
-
68
- // String methods that return new values
69
- let s = "hello";
70
- s.to_uppercase(); // Warning: unused String
71
- ```
72
-
73
- ## When to Apply
74
-
75
- ```rust
76
- // ✅ Pure functions (no side effects)
77
- #[must_use]
78
- fn add(a: i32, b: i32) -> i32 { a + b }
79
-
80
- // ✅ Builder methods returning Self
81
- #[must_use = "builder methods return a new builder"]
82
- fn with_timeout(self, t: Duration) -> Self { ... }
83
-
84
- // ✅ Fallible operations
85
- #[must_use]
86
- fn try_parse(s: &str) -> Result<Data, ParseError> { ... }
87
-
88
- // ✅ Iterators and futures (lazy)
89
- #[must_use = "iterators are lazy and do nothing unless consumed"]
90
- struct Map<I, F> { ... }
91
-
92
- // ❌ Side-effecting functions where result is optional
93
- fn log(msg: &str) -> Result<(), io::Error> { ... } // Might be ok to ignore
94
-
95
- // ❌ Methods with useful side effects
96
- fn vec.push(item); // Mutates vec, no return to use
97
- ```
98
-
99
- ## Custom Messages
100
-
101
- ```rust
102
- #[must_use = "creating a guard does nothing without assignment"]
103
- struct ScopeGuard { ... }
104
-
105
- #[must_use = "this returns the old value"]
106
- fn replace(&mut self, new: T) -> T { ... }
107
-
108
- #[must_use = "use `.await` to execute the future"]
109
- async fn fetch() -> Data { ... }
110
- ```
111
-
112
- ## Clippy Lints
113
-
114
- ```toml
115
- [lints.clippy]
116
- must_use_candidate = "warn" # Suggests where to add #[must_use]
117
- unused_must_use = "deny" # Built-in, treat warnings as errors
118
- double_must_use = "warn" # Redundant #[must_use]
119
- ```
120
-
121
- ## See Also
122
-
123
- - [api-builder-must-use](./api-builder-must-use.md) - Builder pattern must_use
124
- - [err-result-over-panic](./err-result-over-panic.md) - Result types require handling
125
- - [lint-deny-correctness](./lint-deny-correctness.md) - Enabling useful lints