agy-superpowers 5.2.2 → 5.2.4
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.
- package/README.md +47 -150
- package/package.json +1 -1
- package/template/agent/rules/CLAUDE.md +80 -0
- package/template/agent/rules/code-styles.md +31 -32
- package/template/agent/rules/debug-confirmation-policy.md +2 -0
- package/template/agent/rules/file-length-policy.md +2 -0
- package/template/agent/rules/git-policy.md +7 -0
- package/template/agent/rules/language-matching.md +2 -0
- package/template/agent/rules/scratch-scripts.md +39 -0
- package/template/agent/rules/superpowers.md +8 -51
- package/template/agent/skills/executing-plans/SKILL.md +17 -0
- package/template/agent/skills/systematic-debugging/SKILL.md +16 -0
- package/template/agent/skills/test-driven-development/SKILL.md +16 -0
- package/template/agent/skills/verification-before-completion/SKILL.md +22 -0
- package/template/agent/skills/writing-plans/SKILL.md +16 -0
- package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
- package/template/agent/skills/analytics-setup/SKILL.md +0 -51
- package/template/agent/skills/api-design/SKILL.md +0 -193
- package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
- package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
- package/template/agent/skills/backend-developer/SKILL.md +0 -148
- package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
- package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
- package/template/agent/skills/community-manager/SKILL.md +0 -115
- package/template/agent/skills/content-marketer/SKILL.md +0 -111
- package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
- package/template/agent/skills/cto-architect/SKILL.md +0 -133
- package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
- package/template/agent/skills/data-analyst/SKILL.md +0 -147
- package/template/agent/skills/devops-engineer/SKILL.md +0 -117
- package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
- package/template/agent/skills/game-design/SKILL.md +0 -194
- package/template/agent/skills/game-developer/SKILL.md +0 -175
- package/template/agent/skills/growth-hacker/SKILL.md +0 -122
- package/template/agent/skills/idea-validator/SKILL.md +0 -55
- package/template/agent/skills/indie-legal/SKILL.md +0 -53
- package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
- package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
- package/template/agent/skills/launch-strategist/SKILL.md +0 -62
- package/template/agent/skills/market-researcher/SKILL.md +0 -53
- package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
- package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
- package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
- package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
- package/template/agent/skills/real-time-features/SKILL.md +0 -194
- package/template/agent/skills/retention-specialist/SKILL.md +0 -123
- package/template/agent/skills/rust-developer/SKILL.md +0 -281
- package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
- package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
- package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
- package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
- package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
- package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
- package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
- package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
- package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
- package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
- package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
- package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
- package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
- package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
- package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
- package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
- package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
- package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
- package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
- package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
- package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
- package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
- package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
- package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
- package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
- package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
- package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
- package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
- package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
- package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
- package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
- package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
- package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
- package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
- package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
- package/template/agent/skills/saas-architect/SKILL.md +0 -139
- package/template/agent/skills/security-engineer/SKILL.md +0 -133
- package/template/agent/skills/seo-specialist/SKILL.md +0 -130
- package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# mem-with-capacity
|
|
2
|
-
|
|
3
|
-
> Use `with_capacity()` when size is known
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
When you know (or can estimate) the final size of a collection, pre-allocating avoids multiple reallocations as it grows. Each reallocation copies all existing elements, so avoiding them can dramatically improve performance.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Vec starts at capacity 0, reallocates at 4, 8, 16, 32...
|
|
13
|
-
let mut results = Vec::new();
|
|
14
|
-
for i in 0..1000 {
|
|
15
|
-
results.push(process(i)); // ~10 reallocations!
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// String grows similarly
|
|
19
|
-
let mut output = String::new();
|
|
20
|
-
for word in words {
|
|
21
|
-
output.push_str(word);
|
|
22
|
-
output.push(' ');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// HashMap default capacity is small
|
|
26
|
-
let mut map = HashMap::new();
|
|
27
|
-
for (k, v) in pairs { // Many reallocations
|
|
28
|
-
map.insert(k, v);
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Good
|
|
33
|
-
|
|
34
|
-
```rust
|
|
35
|
-
// Pre-allocate exact size
|
|
36
|
-
let mut results = Vec::with_capacity(1000);
|
|
37
|
-
for i in 0..1000 {
|
|
38
|
-
results.push(process(i)); // Zero reallocations!
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Or use collect with size hint (iterator provides capacity)
|
|
42
|
-
let results: Vec<_> = (0..1000).map(process).collect();
|
|
43
|
-
|
|
44
|
-
// Pre-allocate string
|
|
45
|
-
let estimated_len = words.iter().map(|w| w.len() + 1).sum();
|
|
46
|
-
let mut output = String::with_capacity(estimated_len);
|
|
47
|
-
for word in words {
|
|
48
|
-
output.push_str(word);
|
|
49
|
-
output.push(' ');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Pre-allocate HashMap
|
|
53
|
-
let mut map = HashMap::with_capacity(pairs.len());
|
|
54
|
-
for (k, v) in pairs {
|
|
55
|
-
map.insert(k, v);
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Collection Capacity Methods
|
|
60
|
-
|
|
61
|
-
```rust
|
|
62
|
-
// Vec
|
|
63
|
-
let mut v = Vec::with_capacity(100);
|
|
64
|
-
v.reserve(50); // Ensure at least 50 more slots
|
|
65
|
-
v.reserve_exact(50); // Ensure exactly 50 more (no extra)
|
|
66
|
-
v.shrink_to_fit(); // Release unused capacity
|
|
67
|
-
|
|
68
|
-
// String
|
|
69
|
-
let mut s = String::with_capacity(100);
|
|
70
|
-
s.reserve(50);
|
|
71
|
-
|
|
72
|
-
// HashMap / HashSet
|
|
73
|
-
let mut m = HashMap::with_capacity(100);
|
|
74
|
-
m.reserve(50);
|
|
75
|
-
|
|
76
|
-
// VecDeque
|
|
77
|
-
let mut d = VecDeque::with_capacity(100);
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Estimating Capacity
|
|
81
|
-
|
|
82
|
-
```rust
|
|
83
|
-
// From iterator length
|
|
84
|
-
fn collect_results(items: &[Item]) -> Vec<Output> {
|
|
85
|
-
let mut results = Vec::with_capacity(items.len());
|
|
86
|
-
for item in items {
|
|
87
|
-
results.push(process(item));
|
|
88
|
-
}
|
|
89
|
-
results
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// From filter estimate (if ~10% pass filter)
|
|
93
|
-
fn filter_valid(items: &[Item]) -> Vec<&Item> {
|
|
94
|
-
let mut valid = Vec::with_capacity(items.len() / 10);
|
|
95
|
-
for item in items {
|
|
96
|
-
if item.is_valid() {
|
|
97
|
-
valid.push(item);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
valid
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// String from parts
|
|
104
|
-
fn join_with_sep(parts: &[&str], sep: &str) -> String {
|
|
105
|
-
let total_len: usize = parts.iter().map(|p| p.len()).sum();
|
|
106
|
-
let sep_len = if parts.is_empty() { 0 } else { sep.len() * (parts.len() - 1) };
|
|
107
|
-
|
|
108
|
-
let mut result = String::with_capacity(total_len + sep_len);
|
|
109
|
-
for (i, part) in parts.iter().enumerate() {
|
|
110
|
-
if i > 0 {
|
|
111
|
-
result.push_str(sep);
|
|
112
|
-
}
|
|
113
|
-
result.push_str(part);
|
|
114
|
-
}
|
|
115
|
-
result
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Evidence from Production Code
|
|
120
|
-
|
|
121
|
-
From fd (file finder):
|
|
122
|
-
```rust
|
|
123
|
-
// https://github.com/sharkdp/fd/blob/master/src/walk.rs
|
|
124
|
-
struct ReceiverBuffer<'a, W> {
|
|
125
|
-
buffer: Vec<DirEntry>,
|
|
126
|
-
// ...
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
impl<'a, W: Write> ReceiverBuffer<'a, W> {
|
|
130
|
-
fn new(...) -> Self {
|
|
131
|
-
Self {
|
|
132
|
-
buffer: Vec::with_capacity(MAX_BUFFER_LENGTH),
|
|
133
|
-
// ...
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## When to Skip
|
|
140
|
-
|
|
141
|
-
```rust
|
|
142
|
-
// Unknown size, small expected
|
|
143
|
-
let mut small: Vec<i32> = Vec::new(); // OK for small collections
|
|
144
|
-
|
|
145
|
-
// Using collect() with good size_hint
|
|
146
|
-
let v: Vec<_> = iter.collect(); // collect() uses size_hint
|
|
147
|
-
|
|
148
|
-
// Capacity overhead exceeds benefit
|
|
149
|
-
let mut rarely_used = Vec::new(); // OK if rarely grown
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## See Also
|
|
153
|
-
|
|
154
|
-
- [mem-reuse-collections](mem-reuse-collections.md) - Reuse collections with clear()
|
|
155
|
-
- [mem-smallvec](mem-smallvec.md) - Use SmallVec for usually-small collections
|
|
156
|
-
- [perf-extend-batch](perf-extend-batch.md) - Use extend() for batch insertions
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# mem-write-over-format
|
|
2
|
-
|
|
3
|
-
> Use `write!()` into existing buffers instead of `format!()` allocations
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
`format!()` always allocates a new `String`. In hot paths or loops, these allocations add up. `write!()` writes directly into an existing buffer, reusing its capacity. For high-frequency formatting operations, this can eliminate significant allocator overhead.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
fn log_event(event: &Event, output: &mut Vec<u8>) {
|
|
13
|
-
// format! allocates a new String every call
|
|
14
|
-
let line = format!(
|
|
15
|
-
"[{}] {}: {}\n",
|
|
16
|
-
event.timestamp,
|
|
17
|
-
event.level,
|
|
18
|
-
event.message
|
|
19
|
-
);
|
|
20
|
-
output.extend_from_slice(line.as_bytes());
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
fn build_response(items: &[Item]) -> String {
|
|
24
|
-
let mut result = String::new();
|
|
25
|
-
|
|
26
|
-
for item in items {
|
|
27
|
-
// format! allocates for each item
|
|
28
|
-
result.push_str(&format!("{}: {}\n", item.name, item.value));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
result
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Good
|
|
36
|
-
|
|
37
|
-
```rust
|
|
38
|
-
use std::fmt::Write;
|
|
39
|
-
|
|
40
|
-
fn log_event(event: &Event, output: &mut Vec<u8>) {
|
|
41
|
-
use std::io::Write;
|
|
42
|
-
// write! to Vec<u8> directly, no intermediate allocation
|
|
43
|
-
write!(
|
|
44
|
-
output,
|
|
45
|
-
"[{}] {}: {}\n",
|
|
46
|
-
event.timestamp,
|
|
47
|
-
event.level,
|
|
48
|
-
event.message
|
|
49
|
-
).unwrap();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
fn build_response(items: &[Item]) -> String {
|
|
53
|
-
use std::fmt::Write;
|
|
54
|
-
|
|
55
|
-
let mut result = String::with_capacity(items.len() * 64);
|
|
56
|
-
|
|
57
|
-
for item in items {
|
|
58
|
-
// write! into existing String, reuses capacity
|
|
59
|
-
write!(&mut result, "{}: {}\n", item.name, item.value).unwrap();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
result
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Write Trait Varieties
|
|
67
|
-
|
|
68
|
-
```rust
|
|
69
|
-
// std::fmt::Write - for String, &mut String
|
|
70
|
-
use std::fmt::Write as FmtWrite;
|
|
71
|
-
let mut s = String::new();
|
|
72
|
-
write!(&mut s, "Hello {}", 42).unwrap();
|
|
73
|
-
|
|
74
|
-
// std::io::Write - for Vec<u8>, File, TcpStream, etc.
|
|
75
|
-
use std::io::Write as IoWrite;
|
|
76
|
-
let mut v: Vec<u8> = Vec::new();
|
|
77
|
-
write!(&mut v, "Hello {}", 42).unwrap();
|
|
78
|
-
|
|
79
|
-
// Both can fail in principle, but String/Vec never fail
|
|
80
|
-
// Still need .unwrap() due to Result return type
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Reusable Formatting Buffer
|
|
84
|
-
|
|
85
|
-
```rust
|
|
86
|
-
use std::fmt::Write;
|
|
87
|
-
|
|
88
|
-
struct Formatter {
|
|
89
|
-
buffer: String,
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
impl Formatter {
|
|
93
|
-
fn new() -> Self {
|
|
94
|
-
Self { buffer: String::with_capacity(1024) }
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
fn format_event(&mut self, event: &Event) -> &str {
|
|
98
|
-
self.buffer.clear(); // Reuse allocation
|
|
99
|
-
write!(
|
|
100
|
-
&mut self.buffer,
|
|
101
|
-
"[{}] {}",
|
|
102
|
-
event.timestamp,
|
|
103
|
-
event.message
|
|
104
|
-
).unwrap();
|
|
105
|
-
&self.buffer
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Usage
|
|
110
|
-
let mut formatter = Formatter::new();
|
|
111
|
-
for event in events {
|
|
112
|
-
let formatted = formatter.format_event(event);
|
|
113
|
-
send_log(formatted);
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## writeln! for Lines
|
|
118
|
-
|
|
119
|
-
```rust
|
|
120
|
-
use std::fmt::Write;
|
|
121
|
-
|
|
122
|
-
let mut output = String::new();
|
|
123
|
-
|
|
124
|
-
// writeln! adds newline automatically
|
|
125
|
-
writeln!(&mut output, "Line 1: {}", value1).unwrap();
|
|
126
|
-
writeln!(&mut output, "Line 2: {}", value2).unwrap();
|
|
127
|
-
|
|
128
|
-
// Equivalent to
|
|
129
|
-
write!(&mut output, "Line 1: {}\n", value1).unwrap();
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## When format! Is Fine
|
|
133
|
-
|
|
134
|
-
```rust
|
|
135
|
-
// One-time formatting, not in loop
|
|
136
|
-
let message = format!("Starting server on port {}", port);
|
|
137
|
-
log::info!("{}", message);
|
|
138
|
-
|
|
139
|
-
// Return value (can't return reference to local buffer)
|
|
140
|
-
fn describe(item: &Item) -> String {
|
|
141
|
-
format!("{}: {}", item.name, item.value) // Must allocate
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Debug/error paths (not hot)
|
|
145
|
-
if condition {
|
|
146
|
-
panic!("Unexpected: {}", format!("details: {:?}", debug_info));
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## Benchmark Difference
|
|
151
|
-
|
|
152
|
-
```rust
|
|
153
|
-
// format! in loop: ~500ns per iteration (allocation heavy)
|
|
154
|
-
for i in 0..1000 {
|
|
155
|
-
let s = format!("item-{}", i);
|
|
156
|
-
process(&s);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// write! with reuse: ~50ns per iteration (no allocation)
|
|
160
|
-
let mut buf = String::with_capacity(32);
|
|
161
|
-
for i in 0..1000 {
|
|
162
|
-
buf.clear();
|
|
163
|
-
write!(&mut buf, "item-{}", i).unwrap();
|
|
164
|
-
process(&buf);
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## See Also
|
|
169
|
-
|
|
170
|
-
- [mem-avoid-format](./mem-avoid-format.md) - General format! avoidance patterns
|
|
171
|
-
- [mem-reuse-collections](./mem-reuse-collections.md) - Reusing buffers in loops
|
|
172
|
-
- [mem-with-capacity](./mem-with-capacity.md) - Pre-allocating string capacity
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# mem-zero-copy
|
|
2
|
-
|
|
3
|
-
> Use zero-copy patterns with slices and `Bytes`
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Zero-copy means working with data without copying it. Instead of allocating new memory and copying bytes, you work with references to the original data. This dramatically reduces memory usage and improves performance, especially for large data.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Copies every line into a new String
|
|
13
|
-
fn get_lines(data: &str) -> Vec<String> {
|
|
14
|
-
data.lines()
|
|
15
|
-
.map(|line| line.to_string()) // Allocates!
|
|
16
|
-
.collect()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Copies the entire buffer
|
|
20
|
-
fn process_packet(buffer: &[u8]) -> Vec<u8> {
|
|
21
|
-
let header = buffer[0..16].to_vec(); // Copy!
|
|
22
|
-
let body = buffer[16..].to_vec(); // Copy!
|
|
23
|
-
// Process...
|
|
24
|
-
[header, body].concat() // Another copy!
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Good
|
|
29
|
-
|
|
30
|
-
```rust
|
|
31
|
-
// Zero-copy: returns references to original data
|
|
32
|
-
fn get_lines(data: &str) -> Vec<&str> {
|
|
33
|
-
data.lines().collect() // Just pointers!
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Zero-copy with slices
|
|
37
|
-
fn process_packet(buffer: &[u8]) -> (&[u8], &[u8]) {
|
|
38
|
-
let header = &buffer[0..16]; // Just a pointer + length
|
|
39
|
-
let body = &buffer[16..]; // Just a pointer + length
|
|
40
|
-
(header, body)
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Using bytes::Bytes
|
|
45
|
-
|
|
46
|
-
```rust
|
|
47
|
-
use bytes::Bytes;
|
|
48
|
-
|
|
49
|
-
// Bytes provides zero-copy slicing with reference counting
|
|
50
|
-
let data = Bytes::from("hello world");
|
|
51
|
-
|
|
52
|
-
// Slicing doesn't copy - just increments refcount
|
|
53
|
-
let hello = data.slice(0..5); // Zero-copy!
|
|
54
|
-
let world = data.slice(6..11); // Zero-copy!
|
|
55
|
-
|
|
56
|
-
// Both hello and world share the underlying allocation
|
|
57
|
-
// Memory is freed when all references are dropped
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Real-World Pattern from Deno
|
|
61
|
-
|
|
62
|
-
```rust
|
|
63
|
-
// https://github.com/denoland/deno/blob/main/ext/http/lib.rs
|
|
64
|
-
fn method_to_cow(method: &http::Method) -> Cow<'static, str> {
|
|
65
|
-
match *method {
|
|
66
|
-
Method::GET => Cow::Borrowed("GET"), // Zero-copy
|
|
67
|
-
Method::POST => Cow::Borrowed("POST"), // Zero-copy
|
|
68
|
-
Method::PUT => Cow::Borrowed("PUT"), // Zero-copy
|
|
69
|
-
_ => Cow::Owned(method.to_string()), // Only copies for rare methods
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Zero-Copy Parsing
|
|
75
|
-
|
|
76
|
-
```rust
|
|
77
|
-
// Bad: Copies each parsed field
|
|
78
|
-
struct ParsedBad {
|
|
79
|
-
name: String,
|
|
80
|
-
value: String,
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
fn parse_bad(input: &str) -> ParsedBad {
|
|
84
|
-
let (name, value) = input.split_once('=').unwrap();
|
|
85
|
-
ParsedBad {
|
|
86
|
-
name: name.to_string(), // Copy!
|
|
87
|
-
value: value.to_string(), // Copy!
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Good: References into original string
|
|
92
|
-
struct Parsed<'a> {
|
|
93
|
-
name: &'a str,
|
|
94
|
-
value: &'a str,
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
fn parse_good(input: &str) -> Parsed<'_> {
|
|
98
|
-
let (name, value) = input.split_once('=').unwrap();
|
|
99
|
-
Parsed { name, value } // Zero-copy!
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Combining with Cow
|
|
104
|
-
|
|
105
|
-
```rust
|
|
106
|
-
use std::borrow::Cow;
|
|
107
|
-
|
|
108
|
-
// Zero-copy when possible, copy when needed
|
|
109
|
-
fn normalize<'a>(input: &'a str) -> Cow<'a, str> {
|
|
110
|
-
if input.contains('\t') {
|
|
111
|
-
// Must copy to modify
|
|
112
|
-
Cow::Owned(input.replace('\t', " "))
|
|
113
|
-
} else {
|
|
114
|
-
// Zero-copy reference
|
|
115
|
-
Cow::Borrowed(input)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## memchr for Fast Searching
|
|
121
|
-
|
|
122
|
-
```rust
|
|
123
|
-
use memchr::memchr;
|
|
124
|
-
|
|
125
|
-
// Fast byte search using SIMD
|
|
126
|
-
fn find_newline(data: &[u8]) -> Option<usize> {
|
|
127
|
-
memchr(b'\n', data) // SIMD-accelerated, no allocation
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Find all occurrences
|
|
131
|
-
use memchr::memchr_iter;
|
|
132
|
-
|
|
133
|
-
fn count_newlines(data: &[u8]) -> usize {
|
|
134
|
-
memchr_iter(b'\n', data).count()
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## When Zero-Copy Isn't Possible
|
|
139
|
-
|
|
140
|
-
```rust
|
|
141
|
-
// Need to modify data - must copy
|
|
142
|
-
fn uppercase(s: &str) -> String {
|
|
143
|
-
s.to_uppercase() // Creates new String
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Need data to outlive source
|
|
147
|
-
fn store_for_later(s: &str) -> String {
|
|
148
|
-
s.to_string() // Must copy for ownership
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Cross-thread transfer (without Arc)
|
|
152
|
-
fn send_to_thread(data: &[u8]) {
|
|
153
|
-
let owned = data.to_vec(); // Must copy
|
|
154
|
-
std::thread::spawn(move || {
|
|
155
|
-
process(&owned);
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## See Also
|
|
161
|
-
|
|
162
|
-
- [own-cow-conditional](own-cow-conditional.md) - Use Cow for conditional ownership
|
|
163
|
-
- [own-borrow-over-clone](own-borrow-over-clone.md) - Prefer borrowing over cloning
|
|
164
|
-
- [mem-arena-allocator](mem-arena-allocator.md) - Arena allocators for batch operations
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# name-acronym-word
|
|
2
|
-
|
|
3
|
-
> Treat acronyms as words in identifiers: `HttpServer`, not `HTTPServer`
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
When acronyms are written in ALL CAPS within identifiers, word boundaries become unclear: is `HTTPSHandler` "HTTPS Handler" or "HTTP SHandler"? Treating acronyms as words (`HttpsHandler`) maintains clear word boundaries and follows Rust convention. The standard library uses this consistently.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// ALL CAPS acronyms - unclear word boundaries
|
|
13
|
-
struct HTTPServer { ... } // HTTP + Server or H + TTP + Server?
|
|
14
|
-
struct TCPIPConnection { ... } // TCP + IP? Or other splits?
|
|
15
|
-
struct JSONParser { ... }
|
|
16
|
-
struct XMLHTTPRequest { ... } // Very confusing
|
|
17
|
-
|
|
18
|
-
fn parseJSON(input: &str) { ... }
|
|
19
|
-
fn connectTCP(addr: &str) { ... }
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Good
|
|
23
|
-
|
|
24
|
-
```rust
|
|
25
|
-
// Acronyms as words - clear boundaries
|
|
26
|
-
struct HttpServer { ... } // Http + Server
|
|
27
|
-
struct TcpIpConnection { ... } // Tcp + Ip + Connection
|
|
28
|
-
struct JsonParser { ... }
|
|
29
|
-
struct XmlHttpRequest { ... }
|
|
30
|
-
|
|
31
|
-
fn parse_json(input: &str) { ... }
|
|
32
|
-
fn connect_tcp(addr: &str) { ... }
|
|
33
|
-
|
|
34
|
-
// More examples
|
|
35
|
-
struct Uuid { ... } // Not UUID
|
|
36
|
-
struct Uri { ... } // Not URI
|
|
37
|
-
struct Url { ... } // Not URL
|
|
38
|
-
struct Html { ... } // Not HTML
|
|
39
|
-
struct Css { ... } // Not CSS
|
|
40
|
-
struct Api { ... } // Not API
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Standard Library Examples
|
|
44
|
-
|
|
45
|
-
```rust
|
|
46
|
-
// std uses acronyms as words
|
|
47
|
-
std::net::TcpStream // Not TCPStream
|
|
48
|
-
std::net::TcpListener // Not TCPListener
|
|
49
|
-
std::net::UdpSocket // Not UDPSocket
|
|
50
|
-
std::net::IpAddr // Not IPAddr
|
|
51
|
-
std::io::IoError // Not IOError (though Io is acceptable too)
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Two-Letter Acronyms
|
|
55
|
-
|
|
56
|
-
```rust
|
|
57
|
-
// Two-letter acronyms can go either way
|
|
58
|
-
struct Io { ... } // or IO - both acceptable
|
|
59
|
-
struct Id { ... } // or ID - both acceptable
|
|
60
|
-
|
|
61
|
-
// Preference: treat as word for consistency
|
|
62
|
-
struct IoHandler { ... } // Preferred
|
|
63
|
-
struct IdGenerator { ... } // Preferred
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## In snake_case
|
|
67
|
-
|
|
68
|
-
```rust
|
|
69
|
-
// Acronyms become lowercase in snake_case
|
|
70
|
-
fn parse_json() { ... }
|
|
71
|
-
fn connect_tcp() { ... }
|
|
72
|
-
fn generate_uuid() { ... }
|
|
73
|
-
fn fetch_http() { ... }
|
|
74
|
-
fn encode_url() { ... }
|
|
75
|
-
|
|
76
|
-
// Variables
|
|
77
|
-
let json_response = fetch_json();
|
|
78
|
-
let tcp_connection = connect_tcp();
|
|
79
|
-
let user_id = generate_uuid();
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Mixed Cases
|
|
83
|
-
|
|
84
|
-
```rust
|
|
85
|
-
// When acronym is part of compound
|
|
86
|
-
struct HttpsConnection { ... } // Https (not HTTPS)
|
|
87
|
-
struct Utf8String { ... } // Utf8 (not UTF8)
|
|
88
|
-
struct Base64Encoder { ... } // Base64 as word
|
|
89
|
-
|
|
90
|
-
// Multiple acronyms
|
|
91
|
-
struct JsonApiClient { ... } // Json + Api + Client
|
|
92
|
-
struct RestApiHandler { ... } // Rest + Api + Handler
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## See Also
|
|
96
|
-
|
|
97
|
-
- [name-types-camel](./name-types-camel.md) - Type naming conventions
|
|
98
|
-
- [name-funcs-snake](./name-funcs-snake.md) - Function naming conventions
|
|
99
|
-
- [name-consts-screaming](./name-consts-screaming.md) - Constant naming
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
# name-as-free
|
|
2
|
-
|
|
3
|
-
> `as_` prefix: free reference conversion
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Consistent naming helps users understand API cost. `as_` prefix signals a free (O(1), no allocation) conversion that returns a reference. This convention is used throughout the standard library.
|
|
8
|
-
|
|
9
|
-
## The Convention
|
|
10
|
-
|
|
11
|
-
| Prefix | Cost | Ownership | Example |
|
|
12
|
-
|--------|------|-----------|---------|
|
|
13
|
-
| `as_` | Free | `&T -> &U` | `str::as_bytes()` |
|
|
14
|
-
| `to_` | Expensive | `&T -> U` | `str::to_lowercase()` |
|
|
15
|
-
| `into_` | Variable | `T -> U` | `String::into_bytes()` |
|
|
16
|
-
|
|
17
|
-
## Examples
|
|
18
|
-
|
|
19
|
-
```rust
|
|
20
|
-
impl MyString {
|
|
21
|
-
// as_ - free reference conversion
|
|
22
|
-
pub fn as_str(&self) -> &str {
|
|
23
|
-
&self.inner
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn as_bytes(&self) -> &[u8] {
|
|
27
|
-
self.inner.as_bytes()
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
impl Wrapper<T> {
|
|
32
|
-
// as_ - returns reference to inner
|
|
33
|
-
pub fn as_inner(&self) -> &T {
|
|
34
|
-
&self.inner
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
pub fn as_inner_mut(&mut self) -> &mut T {
|
|
38
|
-
&mut self.inner
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Standard Library Examples
|
|
44
|
-
|
|
45
|
-
```rust
|
|
46
|
-
// String
|
|
47
|
-
let s = String::from("hello");
|
|
48
|
-
let bytes: &[u8] = s.as_bytes(); // Free, returns &[u8]
|
|
49
|
-
let str_ref: &str = s.as_str(); // Free, returns &str
|
|
50
|
-
|
|
51
|
-
// Vec
|
|
52
|
-
let v = vec![1, 2, 3];
|
|
53
|
-
let slice: &[i32] = v.as_slice(); // Free, returns &[i32]
|
|
54
|
-
|
|
55
|
-
// Path
|
|
56
|
-
let p = PathBuf::from("/home");
|
|
57
|
-
let path: &Path = p.as_path(); // Free, returns &Path
|
|
58
|
-
|
|
59
|
-
// OsString
|
|
60
|
-
let os = OsString::from("hello");
|
|
61
|
-
let os_str: &OsStr = os.as_os_str(); // Free, returns &OsStr
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Bad
|
|
65
|
-
|
|
66
|
-
```rust
|
|
67
|
-
impl MyType {
|
|
68
|
-
// BAD: as_ but allocates
|
|
69
|
-
pub fn as_string(&self) -> String {
|
|
70
|
-
format!("{}", self.value) // Allocates! Should be to_string()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// BAD: as_ but expensive
|
|
74
|
-
pub fn as_processed(&self) -> &ProcessedData {
|
|
75
|
-
// Actually does expensive computation
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Good
|
|
81
|
-
|
|
82
|
-
```rust
|
|
83
|
-
impl MyType {
|
|
84
|
-
// GOOD: Free reference
|
|
85
|
-
pub fn as_str(&self) -> &str {
|
|
86
|
-
&self.inner
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// GOOD: to_ signals allocation
|
|
90
|
-
pub fn to_string(&self) -> String {
|
|
91
|
-
format!("{}", self.value)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// GOOD: into_ signals ownership transfer
|
|
95
|
-
pub fn into_inner(self) -> Inner {
|
|
96
|
-
self.inner
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## See Also
|
|
102
|
-
|
|
103
|
-
- [name-to-expensive](name-to-expensive.md) - `to_` prefix for expensive conversions
|
|
104
|
-
- [name-into-ownership](name-into-ownership.md) - `into_` prefix for ownership transfer
|