agy-superpowers 5.1.4 → 5.1.5

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 (182) hide show
  1. package/package.json +1 -1
  2. package/template/agent/skills/rust-developer/SKILL.md +281 -0
  3. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +231 -0
  4. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +124 -0
  5. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +131 -0
  6. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +132 -0
  7. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +95 -0
  8. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +141 -0
  9. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +125 -0
  10. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +127 -0
  11. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +120 -0
  12. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +131 -0
  13. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +156 -0
  14. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +122 -0
  15. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +167 -0
  16. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +134 -0
  17. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +143 -0
  18. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +121 -0
  19. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +143 -0
  20. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +187 -0
  21. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +165 -0
  22. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +177 -0
  23. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +163 -0
  24. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +146 -0
  25. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +142 -0
  26. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +160 -0
  27. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +125 -0
  28. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +162 -0
  29. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +177 -0
  30. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +184 -0
  31. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +168 -0
  32. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +182 -0
  33. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +199 -0
  34. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +175 -0
  35. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +185 -0
  36. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +203 -0
  37. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +171 -0
  38. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +158 -0
  39. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +195 -0
  40. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +171 -0
  41. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +156 -0
  42. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +191 -0
  43. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +198 -0
  44. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +154 -0
  45. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +167 -0
  46. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +169 -0
  47. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +172 -0
  48. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +189 -0
  49. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +113 -0
  50. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +147 -0
  51. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +122 -0
  52. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +161 -0
  53. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +149 -0
  54. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +138 -0
  55. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +169 -0
  56. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +116 -0
  57. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +128 -0
  58. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +136 -0
  59. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +131 -0
  60. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +179 -0
  61. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +144 -0
  62. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +152 -0
  63. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +145 -0
  64. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +133 -0
  65. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +152 -0
  66. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +124 -0
  67. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +115 -0
  68. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +151 -0
  69. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +130 -0
  70. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +155 -0
  71. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +171 -0
  72. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +138 -0
  73. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +107 -0
  74. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +154 -0
  75. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +118 -0
  76. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +157 -0
  77. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +133 -0
  78. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +131 -0
  79. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +136 -0
  80. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +135 -0
  81. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +122 -0
  82. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +172 -0
  83. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +168 -0
  84. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +142 -0
  85. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +168 -0
  86. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +147 -0
  87. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +158 -0
  88. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +139 -0
  89. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +147 -0
  90. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +149 -0
  91. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +174 -0
  92. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +159 -0
  93. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +138 -0
  94. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +142 -0
  95. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +156 -0
  96. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +172 -0
  97. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +164 -0
  98. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +99 -0
  99. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +104 -0
  100. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +94 -0
  101. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +78 -0
  102. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +76 -0
  103. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +123 -0
  104. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +127 -0
  105. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +129 -0
  106. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +131 -0
  107. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +142 -0
  108. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +86 -0
  109. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +154 -0
  110. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +118 -0
  111. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +92 -0
  112. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +65 -0
  113. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +101 -0
  114. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +161 -0
  115. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +187 -0
  116. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +142 -0
  117. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +152 -0
  118. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +141 -0
  119. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +181 -0
  120. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +160 -0
  121. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +171 -0
  122. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +130 -0
  123. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +167 -0
  124. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +144 -0
  125. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +154 -0
  126. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +141 -0
  127. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +95 -0
  128. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +135 -0
  129. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +124 -0
  130. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +135 -0
  131. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +134 -0
  132. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +134 -0
  133. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +105 -0
  134. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +65 -0
  135. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +97 -0
  136. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +122 -0
  137. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +119 -0
  138. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +153 -0
  139. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +136 -0
  140. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +133 -0
  141. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +120 -0
  142. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +137 -0
  143. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +134 -0
  144. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +150 -0
  145. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +123 -0
  146. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +113 -0
  147. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +175 -0
  148. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +149 -0
  149. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +142 -0
  150. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +133 -0
  151. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +148 -0
  152. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +130 -0
  153. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +120 -0
  154. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +155 -0
  155. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +139 -0
  156. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +135 -0
  157. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +162 -0
  158. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +186 -0
  159. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +162 -0
  160. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +160 -0
  161. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +151 -0
  162. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +171 -0
  163. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +142 -0
  164. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +168 -0
  165. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +151 -0
  166. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +144 -0
  167. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +189 -0
  168. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +226 -0
  169. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +161 -0
  170. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +130 -0
  171. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +154 -0
  172. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +127 -0
  173. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +154 -0
  174. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +142 -0
  175. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +146 -0
  176. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +160 -0
  177. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +159 -0
  178. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +144 -0
  179. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +137 -0
  180. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +188 -0
  181. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +143 -0
  182. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +131 -0
@@ -0,0 +1,188 @@
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
@@ -0,0 +1,143 @@
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
@@ -0,0 +1,131 @@
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