rust-copy-on-write

Guides choosing between Cow, Arc, and persistent collections for Rust API boundaries and clone-cost decisions.

2|1|Updated Aug 19, 2026
One-click install
npx skills add https://github.com/po4yka/rust-skills --skill rust-copy-on-write-po4yka
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: rust-copy-on-write
Source: https://github.com/po4yka/rust-skills/tree/main/skills/rust-copy-on-write
Command: npx skills add https://github.com/po4yka/rust-skills --skill rust-copy-on-write-po4yka

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Rust developers routinely guess when deciding between borrowed and owned data at API boundaries, or when clone cost drives a data-structure choice. Wrong guesses cause silent allocation blowups, lifetime-infected structs, quadratic version histories, and HashMap lookups that miss present keys. This Skill replaces guessing with measured allocation counts, decision tables, and verification checks. ## Core Features & Use Cases - Cow decision routing: Decision tables route you to the right pattern for Cow<str> in return or argument position, to_mut() misuse, Cow struct fields, and the borrowed-half parameter rule, each backed by measured allocation counts. - Borrow and ToOwned contract repair: Diagnoses and fixes HashMap::get misses caused by Hash/Eq/Borrow contract violations, E0283 ambiguity, E0119 ToOwned conflicts, and unsized newtype pairs like CiStr/CiString. - Persistent collection selection: Compares Vec against im, imbl, and rpds with a measured cost table, covers the rpds Send trap and the 585x write-cost API split, and gates the dependency tree with cargo-deny or cargo audit. - Use Case: You are about to return String from a normalize function where 95% of inputs change nothing. The Skill shows Cow<', str> cuts allocations from 1000 to 50, warns that one caller-side .into_owned() cancels the win, and gives you a counting allocator to verify on your own workload. ## Quick Start Ask the agent to apply the rust-copy-on-write skill to review whether a function returning String should return Cow<', str> instead, and to verify the allocation savings on real input.

Frequently Asked Questions about rust-copy-on-write

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
When should I use Cow<str> instead of String in Rust?▼

Use Cow<'_, str> in return position when most calls change nothing and callers can hold the borrow. Measured over 1000 paths with a 5% rewrite rate, Cow allocates 50 times versus 1000 for String. One caller-side .into_owned() cancels the entire saving.

Why does HashMap::get return None for a key the map contains?▼

The key's Hash or Eq disagrees with its Borrow target, so get probes the wrong bucket. It compiles silently and passes about 1 run in 150 due to RandomState reseeding. Fix it by delegating Hash and Eq to the borrowed half, and pin it with a hash_one test.

im vs imbl vs rpds: which persistent collection crate should I use?▼

Depend on imbl 7.0.2 or later. im is archived with unpatched soundness advisories, and imbl 7.0.1 resolves imbl-sized-chunks 0.1 with a double-free advisory. rpds suits indexed reads but its &self -> Self writes cost 585x more allocations than imbl's &mut self API.

Why is Cow<'_, String> legal but useless in Rust?▼

The blanket impl<T: Clone> ToOwned for T makes Cow<'_, String> type-check, but Cow::Borrowed then holds &String and no &str coerces into it. Write Cow<'_, str>, Cow<'_, [T]>, or Cow<'_, Path> instead; clippy::owned_cow catches the owned forms.

Is rpds::Vector thread-safe for async Rust code?▼

No. rpds::Vector::new() defaults to the Rc-backed RcK archetype, which is not Send and fails with E0277 when crossing threads. Use rpds::Vector::new_sync() for the Arc-backed VectorSync form, and pin the property with an assert_send_sync test.

When should I avoid using Cow in Rust?▼

Avoid Cow when the modification rate exceeds 50%, when the struct must be 'static and cross a task boundary, or when building a version history, since cloning Cow::Owned is quadratic. Use plain String, Arc<str>, or a persistent collection instead.