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,158 @@
1
+ # mem-box-large-variant
2
+
3
+ > Box large enum variants to reduce overall enum size
4
+
5
+ ## Why It Matters
6
+
7
+ An enum's size is determined by its largest variant. If one variant contains a large struct while others are small, every instance of the enum pays for the largest variant's size. Boxing the large variant puts that data on the heap, keeping the enum itself small. This can significantly reduce memory usage and improve cache performance.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ enum Message {
13
+ Quit, // 0 bytes of data
14
+ Move { x: i32, y: i32 }, // 8 bytes
15
+ Text(String), // 24 bytes
16
+ Image {
17
+ data: [u8; 1024], // 1024 bytes - forces entire enum to ~1032 bytes!
18
+ width: u32,
19
+ height: u32
20
+ },
21
+ }
22
+
23
+ // Every Message is ~1032 bytes, even Quit and Move
24
+ let messages: Vec<Message> = vec![
25
+ Message::Quit, // Wastes ~1032 bytes
26
+ Message::Quit, // Wastes ~1032 bytes
27
+ Message::Move { x: 0, y: 0 }, // Wastes ~1024 bytes
28
+ ];
29
+ ```
30
+
31
+ ## Good
32
+
33
+ ```rust
34
+ struct ImageData {
35
+ data: [u8; 1024],
36
+ width: u32,
37
+ height: u32,
38
+ }
39
+
40
+ enum Message {
41
+ Quit,
42
+ Move { x: i32, y: i32 },
43
+ Text(String),
44
+ Image(Box<ImageData>), // Now just 8 bytes (pointer)
45
+ }
46
+
47
+ // Message is now ~32 bytes (String variant is largest)
48
+ let messages: Vec<Message> = vec![
49
+ Message::Quit, // Uses ~32 bytes
50
+ Message::Quit, // Uses ~32 bytes
51
+ Message::Move { x: 0, y: 0 }, // Uses ~32 bytes
52
+ ];
53
+ ```
54
+
55
+ ## Check Enum Sizes
56
+
57
+ ```rust
58
+ use std::mem::size_of;
59
+
60
+ // Before boxing
61
+ enum BadEvent {
62
+ Click { x: u32, y: u32 }, // 8 bytes
63
+ KeyPress(char), // 4 bytes
64
+ LargeData([u8; 256]), // 256 bytes
65
+ }
66
+ println!("BadEvent: {} bytes", size_of::<BadEvent>()); // ~264 bytes
67
+
68
+ // After boxing
69
+ enum GoodEvent {
70
+ Click { x: u32, y: u32 },
71
+ KeyPress(char),
72
+ LargeData(Box<[u8; 256]>), // 8 bytes (pointer)
73
+ }
74
+ println!("GoodEvent: {} bytes", size_of::<GoodEvent>()); // ~16 bytes
75
+ ```
76
+
77
+ ## Clippy Lint
78
+
79
+ ```toml
80
+ [lints.clippy]
81
+ large_enum_variant = "warn" # Warns when variants differ significantly
82
+ ```
83
+
84
+ ```rust
85
+ // Clippy will suggest:
86
+ // warning: large size difference between variants
87
+ // help: consider boxing the large fields to reduce the total size
88
+ ```
89
+
90
+ ## When to Box
91
+
92
+ | Largest Variant | Other Variants | Action |
93
+ |-----------------|----------------|--------|
94
+ | < 64 bytes | Similar size | Don't box |
95
+ | > 128 bytes | Much smaller | Box the large variant |
96
+ | > 256 bytes | Any | Definitely box |
97
+
98
+ ## Recursive Types Require Boxing
99
+
100
+ ```rust
101
+ // Won't compile - infinite size
102
+ enum List {
103
+ Cons(i32, List),
104
+ Nil,
105
+ }
106
+
107
+ // Must box recursive variant
108
+ enum List {
109
+ Cons(i32, Box<List>), // Now finite size
110
+ Nil,
111
+ }
112
+
113
+ // Same for ASTs
114
+ enum Expr {
115
+ Number(i64),
116
+ BinOp {
117
+ op: Op,
118
+ left: Box<Expr>, // Recursive - must box
119
+ right: Box<Expr>,
120
+ },
121
+ }
122
+ ```
123
+
124
+ ## Pattern Matching with Boxed Variants
125
+
126
+ ```rust
127
+ enum Event {
128
+ Small(u32),
129
+ Large(Box<LargeData>),
130
+ }
131
+
132
+ fn handle(event: Event) {
133
+ match event {
134
+ Event::Small(n) => println!("Small: {}", n),
135
+ Event::Large(data) => {
136
+ // data is Box<LargeData>, dereference to access
137
+ println!("Large: {} bytes", data.size);
138
+ }
139
+ }
140
+ }
141
+
142
+ // Or match on reference
143
+ fn handle_ref(event: &Event) {
144
+ match event {
145
+ Event::Small(n) => println!("Small: {}", n),
146
+ Event::Large(data) => {
147
+ // data is &Box<LargeData>, auto-derefs
148
+ println!("Large: {} bytes", data.size);
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## See Also
155
+
156
+ - [own-move-large](./own-move-large.md) - Boxing large types for cheap moves
157
+ - [mem-smallvec](./mem-smallvec.md) - Alternative for inline small collections
158
+ - [lint-deny-correctness](./lint-deny-correctness.md) - Enabling clippy lints
@@ -0,0 +1,139 @@
1
+ # mem-boxed-slice
2
+
3
+ > Use `Box<[T]>` instead of `Vec<T>` for fixed-size heap data
4
+
5
+ ## Why It Matters
6
+
7
+ `Vec<T>` stores three words: pointer, length, and capacity. When you know a collection won't grow, `Box<[T]>` stores only pointer and length (2 words), saving 8 bytes per instance. More importantly, it communicates intent: "this data is fixed-size." For large numbers of fixed collections, this adds up.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ struct Document {
13
+ // Vec signals "might grow" but we never push after creation
14
+ paragraphs: Vec<Paragraph>, // 24 bytes: ptr + len + capacity
15
+ }
16
+
17
+ fn load_document(data: &[u8]) -> Document {
18
+ let paragraphs: Vec<Paragraph> = parse_paragraphs(data);
19
+ // paragraphs has capacity >= len, wasting the capacity field
20
+ Document { paragraphs }
21
+ }
22
+ ```
23
+
24
+ ## Good
25
+
26
+ ```rust
27
+ struct Document {
28
+ // Box<[T]> signals "fixed size" - clear intent
29
+ paragraphs: Box<[Paragraph]>, // 16 bytes: ptr + len (as fat pointer)
30
+ }
31
+
32
+ fn load_document(data: &[u8]) -> Document {
33
+ let paragraphs: Vec<Paragraph> = parse_paragraphs(data);
34
+ Document {
35
+ paragraphs: paragraphs.into_boxed_slice() // Shrinks + converts
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Memory Layout
41
+
42
+ ```rust
43
+ use std::mem::size_of;
44
+
45
+ // Vec: 24 bytes on 64-bit
46
+ assert_eq!(size_of::<Vec<u8>>(), 24); // ptr(8) + len(8) + cap(8)
47
+
48
+ // Box<[T]>: 16 bytes (fat pointer)
49
+ assert_eq!(size_of::<Box<[u8]>>(), 16); // ptr(8) + len(8)
50
+
51
+ // Savings per instance: 8 bytes
52
+ // For 1 million instances: 8 MB saved
53
+ ```
54
+
55
+ ## Conversion Patterns
56
+
57
+ ```rust
58
+ // Vec to Box<[T]>
59
+ let vec: Vec<i32> = vec![1, 2, 3, 4, 5];
60
+ let boxed: Box<[i32]> = vec.into_boxed_slice();
61
+
62
+ // Box<[T]> back to Vec (if you need to grow)
63
+ let vec_again: Vec<i32> = boxed.into_vec();
64
+
65
+ // From iterator
66
+ let boxed: Box<[i32]> = (0..100).collect::<Vec<_>>().into_boxed_slice();
67
+
68
+ // Shrink Vec first if it has excess capacity
69
+ let mut vec = Vec::with_capacity(1000);
70
+ vec.extend(0..10);
71
+ vec.shrink_to_fit(); // Reduce capacity to length
72
+ let boxed = vec.into_boxed_slice(); // Now no wasted allocation
73
+ ```
74
+
75
+ ## When to Use What
76
+
77
+ | Type | Use When |
78
+ |------|----------|
79
+ | `Vec<T>` | Collection may grow/shrink |
80
+ | `Box<[T]>` | Fixed-size, heap-allocated, many instances |
81
+ | `[T; N]` | Fixed-size, stack-allocated, size known at compile time |
82
+ | `&[T]` | Borrowed view, don't need ownership |
83
+
84
+ ## Box<str> for Immutable Strings
85
+
86
+ Same principle applies to strings:
87
+
88
+ ```rust
89
+ use std::mem::size_of;
90
+
91
+ // String: 24 bytes (like Vec<u8>)
92
+ assert_eq!(size_of::<String>(), 24);
93
+
94
+ // Box<str>: 16 bytes
95
+ assert_eq!(size_of::<Box<str>>(), 16);
96
+
97
+ // For immutable strings
98
+ struct Name {
99
+ value: Box<str>, // Saves 8 bytes vs String
100
+ }
101
+
102
+ impl Name {
103
+ fn new(s: &str) -> Self {
104
+ Name { value: s.into() } // &str -> Box<str>
105
+ }
106
+ }
107
+
108
+ // Or from String
109
+ let s = String::from("hello");
110
+ let boxed: Box<str> = s.into_boxed_str();
111
+ ```
112
+
113
+ ## Real-World Example
114
+
115
+ ```rust
116
+ // Cache with millions of entries
117
+ struct Cache {
118
+ // 8 bytes saved per entry adds up
119
+ entries: HashMap<Key, Box<[u8]>>,
120
+ }
121
+
122
+ impl Cache {
123
+ fn insert(&mut self, key: Key, data: Vec<u8>) {
124
+ // Convert to boxed slice for storage
125
+ self.entries.insert(key, data.into_boxed_slice());
126
+ }
127
+
128
+ fn get(&self, key: &Key) -> Option<&[u8]> {
129
+ // Returns regular slice reference
130
+ self.entries.get(key).map(|b| b.as_ref())
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## See Also
136
+
137
+ - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating when size is known
138
+ - [own-slice-over-vec](./own-slice-over-vec.md) - Using slices in function parameters
139
+ - [mem-compact-string](./mem-compact-string.md) - Compact string alternatives
@@ -0,0 +1,147 @@
1
+ # mem-clone-from
2
+
3
+ > Use `clone_from()` to reuse allocations when repeatedly cloning
4
+
5
+ ## Why It Matters
6
+
7
+ `x = y.clone()` drops x's allocation and creates a new one from y. `x.clone_from(&y)` reuses x's existing allocation if possible, avoiding the allocation overhead. For repeatedly cloning into the same variable (loops, buffers), this can significantly reduce allocator pressure.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ let mut buffer = String::with_capacity(1024);
13
+
14
+ for source in sources {
15
+ buffer = source.clone(); // Drops old allocation, allocates new
16
+ process(&buffer);
17
+ }
18
+
19
+ // Each iteration:
20
+ // 1. Drops buffer's 1024-byte allocation
21
+ // 2. Allocates new memory for source.clone()
22
+ // Allocator thrashing!
23
+ ```
24
+
25
+ ## Good
26
+
27
+ ```rust
28
+ let mut buffer = String::with_capacity(1024);
29
+
30
+ for source in sources {
31
+ buffer.clone_from(source); // Reuses allocation if capacity sufficient
32
+ process(&buffer);
33
+ }
34
+
35
+ // If source.len() <= 1024, no allocation happens
36
+ // Just copies bytes into existing buffer
37
+ ```
38
+
39
+ ## How clone_from Works
40
+
41
+ ```rust
42
+ impl Clone for String {
43
+ fn clone(&self) -> Self {
44
+ // Always allocates new memory
45
+ String::from(self.as_str())
46
+ }
47
+
48
+ fn clone_from(&mut self, source: &Self) {
49
+ // Reuse existing capacity if possible
50
+ self.clear();
51
+ self.push_str(source); // Only reallocates if capacity insufficient
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## Types That Benefit
57
+
58
+ ```rust
59
+ // String - reuses capacity
60
+ let mut s = String::with_capacity(100);
61
+ s.clone_from(&other_string);
62
+
63
+ // Vec<T> - reuses capacity
64
+ let mut v: Vec<u8> = Vec::with_capacity(1000);
65
+ v.clone_from(&other_vec);
66
+
67
+ // HashMap - reuses buckets
68
+ let mut map = HashMap::with_capacity(100);
69
+ map.clone_from(&other_map);
70
+
71
+ // PathBuf - reuses capacity
72
+ let mut path = PathBuf::with_capacity(256);
73
+ path.clone_from(&other_path);
74
+ ```
75
+
76
+ ## Benchmarking the Difference
77
+
78
+ ```rust
79
+ use criterion::{black_box, criterion_group, Criterion};
80
+
81
+ fn bench_clone_patterns(c: &mut Criterion) {
82
+ let source = "x".repeat(1000);
83
+
84
+ c.bench_function("clone assignment", |b| {
85
+ let mut buffer = String::new();
86
+ b.iter(|| {
87
+ buffer = black_box(&source).clone();
88
+ });
89
+ });
90
+
91
+ c.bench_function("clone_from", |b| {
92
+ let mut buffer = String::with_capacity(1000);
93
+ b.iter(|| {
94
+ buffer.clone_from(black_box(&source));
95
+ });
96
+ });
97
+ }
98
+ // clone_from is typically 2-3x faster for this pattern
99
+ ```
100
+
101
+ ## Custom Implementations
102
+
103
+ When implementing Clone for your types:
104
+
105
+ ```rust
106
+ #[derive(Debug)]
107
+ struct Buffer {
108
+ data: Vec<u8>,
109
+ metadata: Metadata,
110
+ }
111
+
112
+ impl Clone for Buffer {
113
+ fn clone(&self) -> Self {
114
+ Buffer {
115
+ data: self.data.clone(),
116
+ metadata: self.metadata.clone(),
117
+ }
118
+ }
119
+
120
+ // Optimize clone_from to reuse vec capacity
121
+ fn clone_from(&mut self, source: &Self) {
122
+ self.data.clone_from(&source.data); // Reuses allocation
123
+ self.metadata = source.metadata.clone();
124
+ }
125
+ }
126
+ ```
127
+
128
+ ## When NOT Needed
129
+
130
+ ```rust
131
+ // Single clone - no benefit
132
+ let copy = original.clone(); // Can't reuse, no prior allocation
133
+
134
+ // Small Copy types - no allocation anyway
135
+ let x: i32 = y; // Not even Clone, just Copy
136
+
137
+ // Immutable context
138
+ fn process(data: &String) {
139
+ // Can't use clone_from - would need &mut self
140
+ }
141
+ ```
142
+
143
+ ## See Also
144
+
145
+ - [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating capacity
146
+ - [mem-reuse-collections](./mem-reuse-collections.md) - Reusing collection allocations
147
+ - [own-clone-explicit](./own-clone-explicit.md) - When Clone is appropriate
@@ -0,0 +1,149 @@
1
+ # mem-compact-string
2
+
3
+ > Use compact string types for memory-constrained string storage
4
+
5
+ ## Why It Matters
6
+
7
+ Standard `String` is 24 bytes (pointer + length + capacity). For applications storing millions of short strings, this overhead dominates. Compact string libraries like `compact_str`, `smartstring`, or `ecow` store small strings inline (no heap allocation) and use optimized layouts for larger strings.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ struct User {
13
+ id: u64,
14
+ // Most usernames are < 24 chars, but String is always 24 bytes + heap
15
+ username: String,
16
+ email: String,
17
+ }
18
+
19
+ // 1 million users = 24 bytes * 2 * 1M = 48MB just for String metadata
20
+ // Plus all the heap allocations for actual content
21
+ ```
22
+
23
+ ## Good
24
+
25
+ ```rust
26
+ use compact_str::CompactString;
27
+
28
+ struct User {
29
+ id: u64,
30
+ // CompactString: 24 bytes, but strings ≤ 24 chars are inline (no heap)
31
+ username: CompactString,
32
+ email: CompactString,
33
+ }
34
+
35
+ // Most usernames fit inline = zero heap allocations
36
+ // Same memory footprint as String but way fewer allocations
37
+ ```
38
+
39
+ ## Compact String Libraries
40
+
41
+ ### compact_str
42
+
43
+ ```rust
44
+ use compact_str::CompactString;
45
+
46
+ // Inline storage for strings ≤ 24 bytes
47
+ let small: CompactString = "hello".into(); // No heap allocation
48
+
49
+ // Automatic heap fallback for larger strings
50
+ let large: CompactString = "x".repeat(100).into();
51
+
52
+ // String-like API
53
+ let mut s = CompactString::new("hello");
54
+ s.push_str(" world");
55
+ assert_eq!(s.as_str(), "hello world");
56
+
57
+ // Format macro
58
+ use compact_str::format_compact;
59
+ let s = format_compact!("value: {}", 42);
60
+ ```
61
+
62
+ ### smartstring
63
+
64
+ ```rust
65
+ use smartstring::{SmartString, LazyCompact};
66
+
67
+ // Default is LazyCompact: 24 bytes inline capacity
68
+ let s: SmartString<LazyCompact> = "short string".into();
69
+
70
+ // Compact mode: 23 bytes inline on 64-bit
71
+ use smartstring::Compact;
72
+ let s: SmartString<Compact> = "hello".into();
73
+ ```
74
+
75
+ ### ecow (copy-on-write)
76
+
77
+ ```rust
78
+ use ecow::EcoString;
79
+
80
+ // Clone is O(1) - shares underlying data
81
+ let s1: EcoString = "shared data".into();
82
+ let s2 = s1.clone(); // Cheap, shares allocation
83
+
84
+ // Copy-on-write: only allocates on mutation
85
+ let mut s3 = s1.clone();
86
+ s3.push_str(" modified"); // Now allocates
87
+ ```
88
+
89
+ ## Memory Comparison
90
+
91
+ ```rust
92
+ use std::mem::size_of;
93
+
94
+ // All 24 bytes, but different inline capacities
95
+ assert_eq!(size_of::<String>(), 24);
96
+ assert_eq!(size_of::<compact_str::CompactString>(), 24);
97
+ assert_eq!(size_of::<smartstring::SmartString>(), 24);
98
+ assert_eq!(size_of::<ecow::EcoString>(), 16); // Even smaller!
99
+ ```
100
+
101
+ ## Inline Capacity
102
+
103
+ | Type | Size | Inline Capacity |
104
+ |------|------|-----------------|
105
+ | `String` | 24 | 0 (always heap) |
106
+ | `CompactString` | 24 | 24 bytes |
107
+ | `SmartString<LazyCompact>` | 24 | 23 bytes |
108
+ | `EcoString` | 16 | 15 bytes |
109
+
110
+ ## When to Use
111
+
112
+ ```rust
113
+ // ✅ Good: Many short strings in memory
114
+ struct Dictionary {
115
+ words: Vec<CompactString>, // Millions of short words
116
+ }
117
+
118
+ // ✅ Good: Frequently cloned strings
119
+ struct Template {
120
+ parts: Vec<EcoString>, // O(1) clone
121
+ }
122
+
123
+ // ❌ Don't: Hot path string manipulation
124
+ fn transform(s: &str) -> String {
125
+ // Standard String is optimized for manipulation
126
+ s.to_uppercase()
127
+ }
128
+
129
+ // ❌ Don't: API boundaries (prefer &str or String for interop)
130
+ pub fn public_api(input: CompactString) { } // Forces dependency
131
+ pub fn public_api(input: impl Into<String>) { } // Better
132
+ ```
133
+
134
+ ## Cargo.toml
135
+
136
+ ```toml
137
+ [dependencies]
138
+ compact_str = "0.7"
139
+ # or
140
+ smartstring = "1.0"
141
+ # or
142
+ ecow = "0.2"
143
+ ```
144
+
145
+ ## See Also
146
+
147
+ - [mem-boxed-slice](./mem-boxed-slice.md) - Box<str> for immutable strings
148
+ - [own-cow-conditional](./own-cow-conditional.md) - Cow<str> for borrow-or-own
149
+ - [mem-smallvec](./mem-smallvec.md) - Similar concept for Vec