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,137 +0,0 @@
1
- # type-option-nullable
2
-
3
- > Use `Option<T>` for values that might not exist
4
-
5
- ## Why It Matters
6
-
7
- `Option<T>` explicitly represents "value or nothing" in the type system. Unlike null pointers or sentinel values, you can't accidentally use a missing value—the compiler forces you to handle the `None` case. This eliminates null pointer exceptions at compile time.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Sentinel values - easy to forget to check
13
- fn find_user(id: u64) -> User {
14
- // Returns "empty" user if not found - caller might not check
15
- users.get(&id).cloned().unwrap_or(User::empty())
16
- }
17
-
18
- // Nullable-style with raw pointers
19
- fn find_user(id: u64) -> *const User {
20
- // Null if not found - unsafe, no compiler help
21
- }
22
-
23
- // Error-prone usage
24
- let user = find_user(42);
25
- println!("{}", user.name); // Might be empty user - silent bug
26
- ```
27
-
28
- ## Good
29
-
30
- ```rust
31
- // Option makes absence explicit
32
- fn find_user(id: u64) -> Option<User> {
33
- users.get(&id).cloned()
34
- }
35
-
36
- // Must handle the None case
37
- let user = find_user(42);
38
- match user {
39
- Some(u) => println!("{}", u.name),
40
- None => println!("User not found"),
41
- }
42
-
43
- // Or use combinators
44
- let name = find_user(42)
45
- .map(|u| u.name)
46
- .unwrap_or_else(|| "Unknown".to_string());
47
- ```
48
-
49
- ## Common Option Patterns
50
-
51
- ```rust
52
- // if let for single case
53
- if let Some(user) = find_user(id) {
54
- process(user);
55
- }
56
-
57
- // Chaining with map
58
- let upper_name = find_user(id)
59
- .map(|u| u.name)
60
- .map(|n| n.to_uppercase());
61
-
62
- // Providing defaults
63
- let user = find_user(id).unwrap_or_default();
64
- let user = find_user(id).unwrap_or_else(|| User::guest());
65
-
66
- // ? operator for propagation
67
- fn get_user_email(id: u64) -> Option<String> {
68
- let user = find_user(id)?;
69
- Some(user.email)
70
- }
71
-
72
- // and_then for chained optionals
73
- fn get_user_country(id: u64) -> Option<String> {
74
- find_user(id)
75
- .and_then(|u| u.address)
76
- .and_then(|a| a.country)
77
- }
78
- ```
79
-
80
- ## Struct Fields
81
-
82
- ```rust
83
- struct User {
84
- name: String,
85
- email: String,
86
- phone: Option<String>, // Optional field
87
- avatar_url: Option<Url>, // Optional field
88
- }
89
-
90
- impl User {
91
- fn display_phone(&self) -> &str {
92
- self.phone.as_deref().unwrap_or("Not provided")
93
- }
94
- }
95
- ```
96
-
97
- ## Option vs Result
98
-
99
- ```rust
100
- // Option: value might not exist (no error context)
101
- fn find(key: &str) -> Option<Value> { ... }
102
-
103
- // Result: operation might fail (with error context)
104
- fn parse(input: &str) -> Result<Value, ParseError> { ... }
105
-
106
- // Convert Option to Result
107
- let value = find("key").ok_or(Error::NotFound)?;
108
-
109
- // Convert Result to Option
110
- let value = parse("input").ok(); // Discards error
111
- ```
112
-
113
- ## Option References
114
-
115
- ```rust
116
- // Option<&T> for optional borrows
117
- fn get(&self, key: &str) -> Option<&Value> {
118
- self.map.get(key)
119
- }
120
-
121
- // as_ref() to borrow Option contents
122
- let opt: Option<String> = Some("hello".to_string());
123
- let opt_ref: Option<&String> = opt.as_ref();
124
- let opt_str: Option<&str> = opt.as_deref();
125
-
126
- // as_mut() for mutable borrow
127
- let mut opt = Some(vec![1, 2, 3]);
128
- if let Some(v) = opt.as_mut() {
129
- v.push(4);
130
- }
131
- ```
132
-
133
- ## See Also
134
-
135
- - [type-result-fallible](./type-result-fallible.md) - Result for errors
136
- - [type-enum-states](./type-enum-states.md) - Enums for states
137
- - [err-no-unwrap-prod](./err-no-unwrap-prod.md) - Handling Option safely
@@ -1,188 +0,0 @@
1
- # type-phantom-marker
2
-
3
- > Use `PhantomData` to express type relationships without runtime cost
4
-
5
- ## Why It Matters
6
-
7
- Sometimes your type needs to be parameterized by a type that doesn't appear in any field—for variance, drop order, or semantic purposes. `PhantomData<T>` tells the compiler your type is "associated with" `T` without storing any `T` data. It has zero runtime cost.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Type parameter unused - compiler error
13
- struct Handle<T> {
14
- id: u64,
15
- // Error: parameter `T` is never used
16
- }
17
-
18
- // Workaround with unnecessary storage
19
- struct Handle<T> {
20
- id: u64,
21
- _type: Option<T>, // Wastes memory, requires T: Default
22
- }
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- use std::marker::PhantomData;
29
-
30
- struct Handle<T> {
31
- id: u64,
32
- _marker: PhantomData<T>, // Zero-size, tells compiler about T
33
- }
34
-
35
- impl<T> Handle<T> {
36
- fn new(id: u64) -> Self {
37
- Handle {
38
- id,
39
- _marker: PhantomData,
40
- }
41
- }
42
- }
43
-
44
- // Different Handle types are incompatible
45
- struct User;
46
- struct Order;
47
-
48
- fn process_user(h: Handle<User>) { ... }
49
-
50
- let user_handle = Handle::<User>::new(1);
51
- let order_handle = Handle::<Order>::new(2);
52
-
53
- process_user(user_handle); // OK
54
- process_user(order_handle); // Error: expected Handle<User>, found Handle<Order>
55
- ```
56
-
57
- ## Expressing Ownership
58
-
59
- ```rust
60
- use std::marker::PhantomData;
61
-
62
- // Owns T conceptually (like Box<T>)
63
- struct Container<T> {
64
- ptr: *mut T,
65
- _marker: PhantomData<T>, // Acts like we own a T
66
- }
67
-
68
- // Drop will be called on T when Container drops
69
- impl<T> Drop for Container<T> {
70
- fn drop(&mut self) {
71
- unsafe {
72
- std::ptr::drop_in_place(self.ptr);
73
- }
74
- }
75
- }
76
- ```
77
-
78
- ## Expressing Borrowing
79
-
80
- ```rust
81
- use std::marker::PhantomData;
82
-
83
- // Borrows T for lifetime 'a
84
- struct Ref<'a, T> {
85
- ptr: *const T,
86
- _marker: PhantomData<&'a T>, // Acts like &'a T
87
- }
88
-
89
- // Compiler tracks lifetime correctly
90
- impl<'a, T> Ref<'a, T> {
91
- fn get(&self) -> &'a T {
92
- unsafe { &*self.ptr }
93
- }
94
- }
95
- ```
96
-
97
- ## Type-Level State Machine
98
-
99
- ```rust
100
- use std::marker::PhantomData;
101
-
102
- // States as zero-size types
103
- struct Unlocked;
104
- struct Locked;
105
-
106
- struct Door<State> {
107
- _state: PhantomData<State>,
108
- }
109
-
110
- impl Door<Unlocked> {
111
- fn lock(self) -> Door<Locked> {
112
- println!("Locking...");
113
- Door { _state: PhantomData }
114
- }
115
-
116
- fn open(&self) {
117
- println!("Opening...");
118
- }
119
- }
120
-
121
- impl Door<Locked> {
122
- fn unlock(self) -> Door<Unlocked> {
123
- println!("Unlocking...");
124
- Door { _state: PhantomData }
125
- }
126
-
127
- // Can't call open() on Locked door - method doesn't exist
128
- }
129
-
130
- fn example() {
131
- let door: Door<Unlocked> = Door { _state: PhantomData };
132
- door.open(); // OK
133
- let locked = door.lock();
134
- // locked.open(); // Error: no method `open` for Door<Locked>
135
- let unlocked = locked.unlock();
136
- unlocked.open(); // OK
137
- }
138
- ```
139
-
140
- ## Variance Control
141
-
142
- ```rust
143
- use std::marker::PhantomData;
144
-
145
- // Covariant in T (PhantomData<T>)
146
- struct Producer<T> {
147
- _marker: PhantomData<T>, // Covariant
148
- }
149
-
150
- // Contravariant in T (PhantomData<fn(T)>)
151
- struct Consumer<T> {
152
- _marker: PhantomData<fn(T)>, // Contravariant
153
- }
154
-
155
- // Invariant in T (PhantomData<fn(T) -> T>)
156
- struct Both<T> {
157
- _marker: PhantomData<fn(T) -> T>, // Invariant
158
- }
159
- ```
160
-
161
- ## Common Uses
162
-
163
- ```rust
164
- // 1. FFI handles with type safety
165
- struct FileHandle<T: FileType> {
166
- fd: i32,
167
- _marker: PhantomData<T>,
168
- }
169
-
170
- // 2. Generic iterators
171
- struct Iter<'a, T> {
172
- ptr: *const T,
173
- end: *const T,
174
- _marker: PhantomData<&'a T>,
175
- }
176
-
177
- // 3. Allocator-aware types
178
- struct Vec<T, A: Allocator = Global> {
179
- buf: RawVec<T, A>,
180
- len: usize,
181
- }
182
- ```
183
-
184
- ## See Also
185
-
186
- - [api-typestate](./api-typestate.md) - State machine pattern
187
- - [api-newtype-safety](./api-newtype-safety.md) - Type-safe wrappers
188
- - [type-newtype-ids](./type-newtype-ids.md) - ID types
@@ -1,143 +0,0 @@
1
- # type-repr-transparent
2
-
3
- > Use `#[repr(transparent)]` for newtypes in FFI contexts
4
-
5
- ## Why It Matters
6
-
7
- `#[repr(transparent)]` guarantees a newtype has the same memory layout as its inner type. This is essential for FFI where you need type safety in Rust but must match C ABI layouts. Without it, the compiler may add padding or change layout.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // No layout guarantee - might not match inner type in FFI
13
- struct Handle(u64);
14
-
15
- // Passing to C code might fail
16
- extern "C" {
17
- fn process_handle(h: Handle); // May not work correctly
18
- }
19
-
20
- // Wrapping C type without layout guarantee
21
- struct SafePointer(*mut c_void);
22
- ```
23
-
24
- ## Good
25
-
26
- ```rust
27
- // Guaranteed same layout as inner type
28
- #[repr(transparent)]
29
- struct Handle(u64);
30
-
31
- // Safe for FFI
32
- extern "C" {
33
- fn process_handle(h: Handle); // Works - same layout as u64
34
- }
35
-
36
- // FFI pointer wrapper
37
- #[repr(transparent)]
38
- struct SafePointer(*mut c_void);
39
-
40
- impl SafePointer {
41
- // Safe Rust API around raw pointer
42
- pub fn new(ptr: *mut c_void) -> Option<Self> {
43
- if ptr.is_null() {
44
- None
45
- } else {
46
- Some(SafePointer(ptr))
47
- }
48
- }
49
- }
50
- ```
51
-
52
- ## What repr(transparent) Guarantees
53
-
54
- ```rust
55
- use std::mem::{size_of, align_of};
56
-
57
- #[repr(transparent)]
58
- struct Meters(f64);
59
-
60
- // Same size
61
- assert_eq!(size_of::<Meters>(), size_of::<f64>());
62
-
63
- // Same alignment
64
- assert_eq!(align_of::<Meters>(), align_of::<f64>());
65
-
66
- // Same ABI - can pass where f64 expected
67
- extern "C" fn measure(distance: Meters) { ... }
68
- ```
69
-
70
- ## With PhantomData
71
-
72
- ```rust
73
- use std::marker::PhantomData;
74
-
75
- // PhantomData is zero-sized, doesn't affect layout
76
- #[repr(transparent)]
77
- struct TypedHandle<T> {
78
- raw: u64,
79
- _marker: PhantomData<T>, // Zero-sized, ignored for layout
80
- }
81
-
82
- // Still same layout as u64
83
- assert_eq!(size_of::<TypedHandle<String>>(), size_of::<u64>());
84
- ```
85
-
86
- ## NonZero Wrappers
87
-
88
- ```rust
89
- use std::num::NonZeroU64;
90
-
91
- #[repr(transparent)]
92
- struct NonZeroHandle(NonZeroU64);
93
-
94
- // Inherits null-pointer optimization
95
- assert_eq!(size_of::<Option<NonZeroHandle>>(), size_of::<u64>());
96
- ```
97
-
98
- ## FFI Pattern
99
-
100
- ```rust
101
- mod ffi {
102
- use std::os::raw::c_int;
103
-
104
- #[repr(transparent)]
105
- pub struct FileDescriptor(c_int);
106
-
107
- extern "C" {
108
- pub fn open(path: *const i8, flags: c_int) -> FileDescriptor;
109
- pub fn close(fd: FileDescriptor) -> c_int;
110
- pub fn read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize;
111
- }
112
- }
113
-
114
- // Safe wrapper
115
- pub struct File {
116
- fd: ffi::FileDescriptor,
117
- }
118
-
119
- impl File {
120
- pub fn open(path: &str) -> std::io::Result<Self> {
121
- let c_path = std::ffi::CString::new(path)?;
122
- let fd = unsafe { ffi::open(c_path.as_ptr(), 0) };
123
- // ... error handling
124
- Ok(File { fd })
125
- }
126
- }
127
- ```
128
-
129
- ## When to Use
130
-
131
- | Scenario | Use `#[repr(transparent)]`? |
132
- |----------|----------------------------|
133
- | FFI newtype wrappers | Yes |
134
- | Type-safe handles | Yes |
135
- | NonZero optimization | Yes |
136
- | Pure Rust newtypes | Optional (doesn't hurt) |
137
- | Multi-field structs | N/A (only for single-field) |
138
-
139
- ## See Also
140
-
141
- - [type-newtype-ids](./type-newtype-ids.md) - Newtype pattern
142
- - [type-phantom-marker](./type-phantom-marker.md) - PhantomData usage
143
- - [api-newtype-safety](./api-newtype-safety.md) - Type-safe newtypes
@@ -1,131 +0,0 @@
1
- # type-result-fallible
2
-
3
- > Use `Result<T, E>` for operations that can fail
4
-
5
- ## Why It Matters
6
-
7
- `Result<T, E>` makes failure explicit in the type system. Callers must acknowledge and handle potential errors—they can't accidentally ignore failures. The `?` operator makes error propagation ergonomic while maintaining explicit error handling.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Returning Option loses error context
13
- fn read_config(path: &str) -> Option<Config> {
14
- let content = std::fs::read_to_string(path).ok()?; // Why did it fail?
15
- toml::from_str(&content).ok() // Parse error lost
16
- }
17
-
18
- // Panicking on errors
19
- fn read_config(path: &str) -> Config {
20
- let content = std::fs::read_to_string(path).unwrap(); // Crashes
21
- toml::from_str(&content).unwrap() // Crashes
22
- }
23
-
24
- // Sentinel values
25
- fn divide(a: i32, b: i32) -> i32 {
26
- if b == 0 { return -1; } // Magic value, easy to miss
27
- a / b
28
- }
29
- ```
30
-
31
- ## Good
32
-
33
- ```rust
34
- // Result with clear error type
35
- fn read_config(path: &str) -> Result<Config, ConfigError> {
36
- let content = std::fs::read_to_string(path)
37
- .map_err(ConfigError::IoError)?;
38
- toml::from_str(&content)
39
- .map_err(ConfigError::ParseError)
40
- }
41
-
42
- fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
43
- if b == 0 {
44
- return Err(DivisionError::DivideByZero);
45
- }
46
- Ok(a / b)
47
- }
48
-
49
- // Caller must handle
50
- match divide(10, 0) {
51
- Ok(result) => println!("Result: {}", result),
52
- Err(e) => println!("Error: {}", e),
53
- }
54
- ```
55
-
56
- ## The ? Operator
57
-
58
- ```rust
59
- fn process_file(path: &str) -> Result<ProcessedData, Error> {
60
- let content = std::fs::read_to_string(path)?; // Propagates Err
61
- let parsed: RawData = serde_json::from_str(&content)?;
62
- let validated = validate(parsed)?;
63
- let processed = transform(validated)?;
64
- Ok(processed)
65
- }
66
-
67
- // Equivalent to:
68
- fn process_file(path: &str) -> Result<ProcessedData, Error> {
69
- let content = match std::fs::read_to_string(path) {
70
- Ok(c) => c,
71
- Err(e) => return Err(e.into()),
72
- };
73
- // ... etc
74
- }
75
- ```
76
-
77
- ## Result Combinators
78
-
79
- ```rust
80
- let result: Result<i32, Error> = Ok(42);
81
-
82
- // map: transform success value
83
- let doubled = result.map(|n| n * 2); // Ok(84)
84
-
85
- // map_err: transform error
86
- let with_context = result.map_err(|e| format!("Failed: {}", e));
87
-
88
- // and_then: chain fallible operations
89
- let processed = result.and_then(|n| {
90
- if n > 0 { Ok(n * 2) } else { Err(Error::Negative) }
91
- });
92
-
93
- // unwrap_or: provide default on error
94
- let value = result.unwrap_or(0);
95
-
96
- // ok(): convert to Option, discarding error
97
- let maybe_value: Option<i32> = result.ok();
98
- ```
99
-
100
- ## Defining Error Types
101
-
102
- ```rust
103
- use thiserror::Error;
104
-
105
- #[derive(Error, Debug)]
106
- pub enum ConfigError {
107
- #[error("failed to read file: {0}")]
108
- Io(#[from] std::io::Error),
109
-
110
- #[error("failed to parse config: {0}")]
111
- Parse(#[from] toml::de::Error),
112
-
113
- #[error("missing required field: {0}")]
114
- MissingField(String),
115
- }
116
-
117
- fn load_config(path: &str) -> Result<Config, ConfigError> {
118
- let content = std::fs::read_to_string(path)?; // Io error
119
- let config: Config = toml::from_str(&content)?; // Parse error
120
- if config.name.is_empty() {
121
- return Err(ConfigError::MissingField("name".into()));
122
- }
123
- Ok(config)
124
- }
125
- ```
126
-
127
- ## See Also
128
-
129
- - [err-thiserror-lib](./err-thiserror-lib.md) - Defining error types
130
- - [err-question-mark](./err-question-mark.md) - Using ? operator
131
- - [type-option-nullable](./type-option-nullable.md) - Option vs Result