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,131 +0,0 @@
1
- # doc-safety-section
2
-
3
- > Include `# Safety` section for unsafe functions
4
-
5
- ## Why It Matters
6
-
7
- Unsafe functions require callers to uphold invariants that the compiler cannot verify. The `# Safety` section documents exactly what the caller must guarantee for the function to be sound. Without this, users cannot safely call the function.
8
-
9
- This is not optional—it's a requirement for sound unsafe code.
10
-
11
- ## Bad
12
-
13
- ```rust
14
- /// Reads a value from a raw pointer.
15
- pub unsafe fn read_ptr<T>(ptr: *const T) -> T {
16
- // What guarantees must the caller provide? Unknown!
17
- ptr.read()
18
- }
19
-
20
- /// Creates a string from raw parts.
21
- pub unsafe fn string_from_raw(ptr: *mut u8, len: usize, cap: usize) -> String {
22
- String::from_raw_parts(ptr, len, cap)
23
- }
24
- ```
25
-
26
- ## Good
27
-
28
- ```rust
29
- /// Reads a value from a raw pointer.
30
- ///
31
- /// # Safety
32
- ///
33
- /// The caller must ensure that:
34
- /// - `ptr` is valid for reads of `size_of::<T>()` bytes
35
- /// - `ptr` is properly aligned for type `T`
36
- /// - `ptr` points to a properly initialized value of type `T`
37
- /// - The memory referenced by `ptr` is not mutated during this call
38
- pub unsafe fn read_ptr<T>(ptr: *const T) -> T {
39
- ptr.read()
40
- }
41
-
42
- /// Creates a `String` from raw parts.
43
- ///
44
- /// # Safety
45
- ///
46
- /// The caller must guarantee that:
47
- /// - `ptr` was allocated by the same allocator that `String` uses
48
- /// - `len` is less than or equal to `cap`
49
- /// - The first `len` bytes at `ptr` are valid UTF-8
50
- /// - `cap` is the capacity that `ptr` was allocated with
51
- /// - No other code will use `ptr` after this call (ownership is transferred)
52
- ///
53
- /// Violating these requirements leads to undefined behavior including
54
- /// memory corruption, use-after-free, or invalid UTF-8 in strings.
55
- pub unsafe fn string_from_raw(ptr: *mut u8, len: usize, cap: usize) -> String {
56
- String::from_raw_parts(ptr, len, cap)
57
- }
58
- ```
59
-
60
- ## Key Elements of Safety Documentation
61
-
62
- | Element | Description |
63
- |---------|-------------|
64
- | **Preconditions** | What must be true before calling |
65
- | **Pointer validity** | Alignment, null-ness, lifetime |
66
- | **Memory ownership** | Who owns what, transfer semantics |
67
- | **Invariants** | Type invariants that must hold |
68
- | **Consequences** | What happens if violated |
69
-
70
- ## Pattern: Unsafe Trait Implementations
71
-
72
- ```rust
73
- /// A type that can be safely zeroed.
74
- ///
75
- /// # Safety
76
- ///
77
- /// Implementing this trait guarantees that:
78
- /// - All bit patterns of zeros represent a valid value of this type
79
- /// - The type has no padding bytes that could leak data
80
- /// - The type contains no references or pointers
81
- pub unsafe trait Zeroable {
82
- fn zeroed() -> Self;
83
- }
84
-
85
- // SAFETY: u32 is a primitive integer type where all zero bits
86
- // represent a valid value (0).
87
- unsafe impl Zeroable for u32 {
88
- fn zeroed() -> Self {
89
- 0
90
- }
91
- }
92
- ```
93
-
94
- ## Pattern: Unsafe Blocks in Safe Functions
95
-
96
- When a safe function contains unsafe blocks, document the invariants:
97
-
98
- ```rust
99
- /// Returns a reference to the element at the given index.
100
- ///
101
- /// Returns `None` if the index is out of bounds.
102
- pub fn get(&self, index: usize) -> Option<&T> {
103
- if index < self.len {
104
- // SAFETY: We just verified that index < len, so this
105
- // access is within bounds.
106
- Some(unsafe { self.data.get_unchecked(index) })
107
- } else {
108
- None
109
- }
110
- }
111
- ```
112
-
113
- ## Common Safety Requirements
114
-
115
- ```rust
116
- /// # Safety
117
- ///
118
- /// - Pointer must be non-null
119
- /// - Pointer must be aligned to `align_of::<T>()`
120
- /// - Pointer must be valid for reads/writes of `size_of::<T>()` bytes
121
- /// - Pointer must point to an initialized value of `T`
122
- /// - The referenced memory must not be accessed through any other pointer
123
- /// for the duration of the returned reference
124
- /// - The total size must not exceed `isize::MAX`
125
- ```
126
-
127
- ## See Also
128
-
129
- - [doc-panics-section](./doc-panics-section.md) - Documenting panics
130
- - [lint-unsafe-doc](./lint-unsafe-doc.md) - Enforcing unsafe documentation
131
- - [doc-errors-section](./doc-errors-section.md) - Documenting errors
@@ -1,179 +0,0 @@
1
- # err-anyhow-app
2
-
3
- > Use `anyhow` for application error handling
4
-
5
- ## Why It Matters
6
-
7
- Applications often don't need typed errors - they just need to report what went wrong with good context. `anyhow` provides easy error handling with context chaining, backtraces, and conversion from any error type.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Tedious type management
13
- fn load_config() -> Result<Config, Box<dyn std::error::Error>> {
14
- let path = find_config()?; // Returns FindError
15
- let content = std::fs::read_to_string(&path)?; // Returns io::Error
16
- let config: Config = toml::from_str(&content)?; // Returns toml::Error
17
- validate(&config)?; // Returns ValidationError
18
- Ok(config)
19
- }
20
-
21
- // No context - hard to debug
22
- fn process() -> Result<(), Box<dyn std::error::Error>> {
23
- let data = fetch()?; // Which fetch failed?
24
- transform(data)?; // What was being transformed?
25
- save()?; // Where was it saving to?
26
- Ok(())
27
- }
28
- ```
29
-
30
- ## Good
31
-
32
- ```rust
33
- use anyhow::{Context, Result};
34
-
35
- fn load_config() -> Result<Config> {
36
- let path = find_config()
37
- .context("failed to locate config file")?;
38
-
39
- let content = std::fs::read_to_string(&path)
40
- .with_context(|| format!("failed to read config from {}", path.display()))?;
41
-
42
- let config: Config = toml::from_str(&content)
43
- .context("failed to parse config as TOML")?;
44
-
45
- validate(&config)
46
- .context("config validation failed")?;
47
-
48
- Ok(config)
49
- }
50
-
51
- // Error message: "config validation failed: field 'port' must be > 0"
52
- // Full chain preserved for debugging
53
- ```
54
-
55
- ## Key Features
56
-
57
- ```rust
58
- use anyhow::{anyhow, bail, ensure, Context, Result};
59
-
60
- fn example() -> Result<()> {
61
- // Create ad-hoc errors
62
- let err = anyhow!("something went wrong");
63
-
64
- // Early return with error
65
- bail!("aborting due to {}", reason);
66
-
67
- // Assert with error
68
- ensure!(condition, "condition was false");
69
-
70
- // Add context to any error
71
- risky_operation()
72
- .context("risky operation failed")?;
73
-
74
- // Dynamic context
75
- fetch(url)
76
- .with_context(|| format!("failed to fetch {}", url))?;
77
-
78
- Ok(())
79
- }
80
- ```
81
-
82
- ## Main Function Pattern
83
-
84
- ```rust
85
- use anyhow::Result;
86
-
87
- fn main() -> Result<()> {
88
- let config = load_config()?;
89
- run_app(config)?;
90
- Ok(())
91
- }
92
-
93
- // Or with custom exit handling
94
- fn main() {
95
- if let Err(e) = run() {
96
- eprintln!("Error: {:#}", e); // Pretty-print with causes
97
- std::process::exit(1);
98
- }
99
- }
100
-
101
- fn run() -> Result<()> {
102
- // Application logic
103
- Ok(())
104
- }
105
- ```
106
-
107
- ## Error Display Formats
108
-
109
- ```rust
110
- use anyhow::Result;
111
-
112
- fn show_error(err: anyhow::Error) {
113
- // Just the top-level message
114
- println!("{}", err);
115
- // "config validation failed"
116
-
117
- // With cause chain (# alternate format)
118
- println!("{:#}", err);
119
- // "config validation failed: field 'port' must be > 0"
120
-
121
- // Debug format with backtrace
122
- println!("{:?}", err);
123
- // Full backtrace if RUST_BACKTRACE=1
124
-
125
- // Iterate through cause chain
126
- for cause in err.chain() {
127
- println!("Caused by: {}", cause);
128
- }
129
- }
130
- ```
131
-
132
- ## Combining with thiserror
133
-
134
- ```rust
135
- // In your library crate - typed errors
136
- use thiserror::Error;
137
-
138
- #[derive(Error, Debug)]
139
- pub enum ApiError {
140
- #[error("rate limited")]
141
- RateLimited,
142
- #[error("not found: {0}")]
143
- NotFound(String),
144
- }
145
-
146
- // In your application - anyhow for handling
147
- use anyhow::{Context, Result};
148
-
149
- fn fetch_user(id: u64) -> Result<User> {
150
- api::get_user(id)
151
- .with_context(|| format!("failed to fetch user {}", id))
152
- }
153
-
154
- // Can still downcast if needed
155
- fn handle_error(err: anyhow::Error) {
156
- if let Some(api_err) = err.downcast_ref::<ApiError>() {
157
- match api_err {
158
- ApiError::RateLimited => wait_and_retry(),
159
- ApiError::NotFound(id) => log_missing(id),
160
- }
161
- }
162
- }
163
- ```
164
-
165
- ## When to Use Which
166
-
167
- | Situation | Use |
168
- |-----------|-----|
169
- | Library public API | `thiserror` |
170
- | Application code | `anyhow` |
171
- | CLI tools | `anyhow` |
172
- | Internal library code | Either |
173
- | Need to match error variants | `thiserror` |
174
- | Just need to report errors | `anyhow` |
175
-
176
- ## See Also
177
-
178
- - [err-thiserror-lib](err-thiserror-lib.md) - Use thiserror for libraries
179
- - [err-context-chain](err-context-chain.md) - Add context to errors
@@ -1,144 +0,0 @@
1
- # err-context-chain
2
-
3
- > Add context with `.context()` or `.with_context()`
4
-
5
- ## Why It Matters
6
-
7
- Raw errors often lack information about what operation failed. Adding context creates an error chain that tells the full story: what you were trying to do, and why it failed.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Raw error - no context
13
- fn load_user(id: u64) -> Result<User, Error> {
14
- let path = format!("users/{}.json", id);
15
- let content = std::fs::read_to_string(&path)?;
16
- Ok(serde_json::from_str(&content)?)
17
- }
18
-
19
- // Error message: "No such file or directory (os error 2)"
20
- // Which file? What were we doing?
21
- ```
22
-
23
- ## Good
24
-
25
- ```rust
26
- use anyhow::{Context, Result};
27
-
28
- fn load_user(id: u64) -> Result<User> {
29
- let path = format!("users/{}.json", id);
30
-
31
- let content = std::fs::read_to_string(&path)
32
- .with_context(|| format!("failed to read user file: {}", path))?;
33
-
34
- let user: User = serde_json::from_str(&content)
35
- .with_context(|| format!("failed to parse user {} JSON", id))?;
36
-
37
- Ok(user)
38
- }
39
-
40
- // Error: "failed to parse user 42 JSON"
41
- // Caused by: "expected ':' at line 5 column 12"
42
- ```
43
-
44
- ## context() vs with_context()
45
-
46
- ```rust
47
- // context() - static string (slight allocation)
48
- fs::read_to_string(path)
49
- .context("failed to read config")?;
50
-
51
- // with_context() - lazy evaluation (only allocates on error)
52
- fs::read_to_string(path)
53
- .with_context(|| format!("failed to read {}", path))?;
54
-
55
- // Use with_context() when:
56
- // - Message includes runtime data (format!)
57
- // - Computing the message is expensive
58
- // - Error path is cold (most of the time)
59
- ```
60
-
61
- ## Building Context Chains
62
-
63
- ```rust
64
- fn process_order(order_id: u64) -> Result<()> {
65
- let order = fetch_order(order_id)
66
- .with_context(|| format!("failed to fetch order {}", order_id))?;
67
-
68
- let user = load_user(order.user_id)
69
- .with_context(|| format!("failed to load user for order {}", order_id))?;
70
-
71
- let payment = process_payment(&order, &user)
72
- .context("payment processing failed")?;
73
-
74
- ship_order(&order, &payment)
75
- .context("shipping failed")?;
76
-
77
- Ok(())
78
- }
79
-
80
- // Full error chain:
81
- // "shipping failed"
82
- // Caused by: "carrier API returned 503"
83
- // Caused by: "connection refused"
84
- ```
85
-
86
- ## Displaying Error Chains
87
-
88
- ```rust
89
- fn main() {
90
- if let Err(e) = run() {
91
- // Just top-level message
92
- eprintln!("Error: {}", e);
93
-
94
- // Full chain with alternate format
95
- eprintln!("Error: {:#}", e);
96
-
97
- // Debug format (includes backtrace if enabled)
98
- eprintln!("Error: {:?}", e);
99
-
100
- // Iterate through chain
101
- for (i, cause) in e.chain().enumerate() {
102
- eprintln!(" {}: {}", i, cause);
103
- }
104
- }
105
- }
106
- ```
107
-
108
- ## With thiserror
109
-
110
- ```rust
111
- use thiserror::Error;
112
-
113
- #[derive(Error, Debug)]
114
- pub enum AppError {
115
- #[error("failed to load config from {path}")]
116
- ConfigLoad {
117
- path: String,
118
- #[source]
119
- cause: std::io::Error,
120
- },
121
-
122
- #[error("failed to connect to database")]
123
- Database {
124
- #[source]
125
- cause: sqlx::Error,
126
- },
127
- }
128
-
129
- // Usage
130
- fn load_config(path: &str) -> Result<Config, AppError> {
131
- let content = std::fs::read_to_string(path)
132
- .map_err(|e| AppError::ConfigLoad {
133
- path: path.to_string(),
134
- cause: e,
135
- })?;
136
- // ...
137
- }
138
- ```
139
-
140
- ## See Also
141
-
142
- - [err-anyhow-app](err-anyhow-app.md) - Use anyhow for applications
143
- - [err-source-chain](err-source-chain.md) - Use #[source] to chain errors
144
- - [err-question-mark](err-question-mark.md) - Use ? for propagation
@@ -1,152 +0,0 @@
1
- # err-custom-type
2
-
3
- > Define custom error types for domain-specific failures
4
-
5
- ## Why It Matters
6
-
7
- Generic errors like `String`, `Box<dyn Error>`, or catch-all enums obscure what can actually go wrong. Custom error types document failure modes in the type system, enable pattern matching for specific handling, and provide clear API contracts. They make your code self-documenting and help callers handle errors appropriately.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Generic string errors - no structure
13
- fn validate_user(user: &User) -> Result<(), String> {
14
- if user.name.is_empty() {
15
- return Err("Name is empty".to_string());
16
- }
17
- if user.age > 150 {
18
- return Err("Age is invalid".to_string());
19
- }
20
- Ok(())
21
- }
22
-
23
- // Caller can't match on specific errors
24
- match validate_user(&user) {
25
- Ok(()) => save(user),
26
- Err(msg) => {
27
- // Can only do string comparison - fragile!
28
- if msg.contains("Name") {
29
- prompt_for_name()
30
- }
31
- }
32
- }
33
- ```
34
-
35
- ## Good
36
-
37
- ```rust
38
- use thiserror::Error;
39
-
40
- #[derive(Error, Debug)]
41
- pub enum ValidationError {
42
- #[error("name cannot be empty")]
43
- EmptyName,
44
-
45
- #[error("name exceeds maximum length of {max} characters")]
46
- NameTooLong { max: usize, actual: usize },
47
-
48
- #[error("invalid age {0}: must be between 0 and 150")]
49
- InvalidAge(u8),
50
-
51
- #[error("email format is invalid: {0}")]
52
- InvalidEmail(String),
53
- }
54
-
55
- fn validate_user(user: &User) -> Result<(), ValidationError> {
56
- if user.name.is_empty() {
57
- return Err(ValidationError::EmptyName);
58
- }
59
- if user.name.len() > 100 {
60
- return Err(ValidationError::NameTooLong {
61
- max: 100,
62
- actual: user.name.len()
63
- });
64
- }
65
- if user.age > 150 {
66
- return Err(ValidationError::InvalidAge(user.age));
67
- }
68
- Ok(())
69
- }
70
-
71
- // Caller can match specifically
72
- match validate_user(&user) {
73
- Ok(()) => save(user),
74
- Err(ValidationError::EmptyName) => prompt_for_name(),
75
- Err(ValidationError::InvalidAge(age)) => {
76
- show_error(&format!("Please enter a valid age (you entered {})", age))
77
- }
78
- Err(e) => show_error(&e.to_string()),
79
- }
80
- ```
81
-
82
- ## Error Type Design Guidelines
83
-
84
- ```rust
85
- // 1. Group related errors in domain-specific enums
86
- #[derive(Error, Debug)]
87
- pub enum AuthError {
88
- #[error("invalid credentials")]
89
- InvalidCredentials,
90
- #[error("account locked after {attempts} failed attempts")]
91
- AccountLocked { attempts: u32 },
92
- #[error("token expired")]
93
- TokenExpired,
94
- }
95
-
96
- #[derive(Error, Debug)]
97
- pub enum PaymentError {
98
- #[error("insufficient funds: need {required}, have {available}")]
99
- InsufficientFunds { required: Decimal, available: Decimal },
100
- #[error("card declined: {reason}")]
101
- CardDeclined { reason: String },
102
- }
103
-
104
- // 2. Include relevant data for error handling/display
105
- #[derive(Error, Debug)]
106
- pub enum FileError {
107
- #[error("file not found: {path}")]
108
- NotFound { path: PathBuf },
109
- #[error("permission denied for {path}")]
110
- PermissionDenied { path: PathBuf },
111
- }
112
-
113
- // 3. Consider #[non_exhaustive] for public APIs
114
- #[derive(Error, Debug)]
115
- #[non_exhaustive] // Allows adding variants without breaking changes
116
- pub enum ApiError {
117
- #[error("rate limited")]
118
- RateLimited,
119
- #[error("not found")]
120
- NotFound,
121
- }
122
- ```
123
-
124
- ## When to Use What
125
-
126
- | Error Pattern | Use Case |
127
- |---------------|----------|
128
- | Custom enum | Library with specific failure modes |
129
- | `thiserror` | Libraries needing `std::error::Error` |
130
- | `anyhow::Error` | Applications, prototypes |
131
- | Struct with source | Single error type with wrapped cause |
132
-
133
- ## Struct-Based Errors
134
-
135
- For single error types with rich context:
136
-
137
- ```rust
138
- #[derive(Error, Debug)]
139
- #[error("query failed for table '{table}' with filter '{filter}'")]
140
- pub struct QueryError {
141
- pub table: String,
142
- pub filter: String,
143
- #[source]
144
- pub source: DatabaseError,
145
- }
146
- ```
147
-
148
- ## See Also
149
-
150
- - [err-thiserror-lib](./err-thiserror-lib.md) - thiserror for error definitions
151
- - [err-anyhow-app](./err-anyhow-app.md) - When to use anyhow instead
152
- - [api-non-exhaustive](./api-non-exhaustive.md) - Forward-compatible enums