Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when writing, reviewing, or refactoring Rust code, especially workspace crates, public APIs, error handling, async code, ownership choices, or performance-sensitive paths.
.claude/skills/mkurman-rust-programming/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-19 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-03 | ✓→✗ | ▼ Worse | 23% | 0% |
| case-08 | ✓→✗ | ▼ Worse | 22% | 0% |
| case-20 | ✓→✗ | ▼ Worse | 101% | 0% |
Use this skill to keep Rust changes idiomatic, maintainable, and easy to verify.
Result for recoverable failures and reserve panic!, unwrap, and expect for tests, impossible states with a clear message, or process-fatal startup validation.cargo fmt, focused cargo test, and cargo clippy --workspace --all-targets when the change warrants it.rust// Avoid: forces callers to allocate or give up ownership. fn load_config(path: PathBuf) -> Result<Config, ConfigError> { std::fs::read_to_string(path)?.parse() } // Prefer: accepts Path, PathBuf, and path-like wrappers. fn load_config(path: impl AsRef<std::path::Path>) -> Result<Config, ConfigError> { std::fs::read_to_string(path)?.parse() }
rust#[derive(Debug, thiserror::Error)] pub enum ImportError { #[error("failed to read import file {path}")] Read { path: std::path::PathBuf, #[source] source: std::io::Error, }, #[error("invalid import payload")] InvalidPayload(#[from] serde_json::Error), }
Use typed variants when callers can recover differently. Use context-rich messages at process or UI boundaries where diagnosis matters more than matching.
rustpub struct NonEmptyName(String); impl NonEmptyName { pub fn parse(value: String) -> Result<Self, NameError> { if value.trim().is_empty() { return Err(NameError::Empty); } Ok(Self(value)) } pub fn as_str(&self) -> &str { &self.0 } }
Do validation once at construction instead of repeatedly checking raw strings throughout the codebase.
rust// Avoid: the lock stays held while the async write waits. async fn save_bad(state: &tokio::sync::Mutex<State>, store: &Store) -> anyhow::Result<()> { let guard = state.lock().await; store.write(&guard.snapshot()).await } // Prefer: copy the data needed, then release the lock before await. async fn save_good(state: &tokio::sync::Mutex<State>, store: &Store) -> anyhow::Result<()> { let snapshot = { let guard = state.lock().await; guard.snapshot() }; store.write(&snapshot).await }
rustlet workspace_id = workspace.id.clone(); tokio::spawn(async move { refresh_workspace(workspace_id).await });
Cloning for a spawned task, channel message, cache entry, or stored value is often correct. Cloning to satisfy the borrow checker inside one synchronous function is a signal to shorten borrows first.
rust#[test] fn rejects_empty_workspace_name() { let err = NonEmptyName::parse(" ".to_string()).unwrap_err(); assert!(matches!(err, NameError::Empty)); }
Prefer tests that pin public behavior, error variants, state transitions, and regression cases.
Read references/idiomatic-rust.md for concrete patterns and review heuristics.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 14,712 | 16,183 | +10% | 1 | 1 | 0% | 2,544 | 3,785 | +49% | 0 | 0 | — |
case-02 | fail→fail | 16,419 | 6,207 | -62% | 1 | 1 | 0% | 1,891 | 2,232 | +18% | 0 | 0 | — |
case-03 | pass→fail | 16,498 | 9,295 | -44% | 1 | 1 | 0% | 2,318 | 2,854 | +23% | 0 | 0 | — |
case-04 | pass→pass | 12,020 | 9,836 | -18% | 1 | 1 | 0% | 2,268 | 2,634 | +16% | 0 | 0 | — |
case-05 | fail→fail | 12,587 | 11,197 | -11% | 1 | 1 | 0% | 2,570 | 2,983 | +16% | 0 | 0 | — |
case-06 | fail→fail | 9,428 | 5,242 | -44% | 1 | 1 | 0% | 1,499 | 1,975 | +32% | 0 | 0 | — |
case-07 | pass→pass | 11,994 | 9,611 | -20% | 1 | 1 | 0% | 2,027 | 2,701 | +33% | 0 | 0 | — |
case-08 | pass→fail | 11,712 | 10,516 | -10% | 1 | 1 | 0% | 2,050 | 2,496 | +22% | 0 | 0 | — |
case-09 | pass→pass | 11,132 | 10,748 | -3% | 1 | 1 | 0% | 2,168 | 3,101 | +43% | 0 | 0 | — |
case-10 | pass→pass | 9,325 | 7,564 | -19% | 1 | 1 | 0% | 1,674 | 2,354 | +41% | 0 | 0 | — |
case-11 | fail→fail | 11,495 | 8,408 | -27% | 1 | 1 | 0% | 2,259 | 2,711 | +20% | 0 | 0 | — |
case-12 | pass→pass | 10,558 | 8,090 | -23% | 1 | 1 | 0% | 2,024 | 2,493 | +23% | 0 | 0 | — |
case-13 | pass→pass | 12,251 | 12,676 | +3% | 1 | 1 | 0% | 2,248 | 3,423 | +52% | 0 | 0 | — |
case-14 | pass→pass | 13,266 | 8,091 | -39% | 1 | 1 | 0% | 2,233 | 2,328 | +4% | 0 | 0 | — |
case-15 | pass→pass | 8,097 | 5,751 | -29% | 1 | 1 | 0% | 1,345 | 2,124 | +58% | 0 | 0 | — |
case-16 | pass→pass | 9,798 | 8,607 | -12% | 1 | 1 | 0% | 1,714 | 2,261 | +32% | 0 | 0 | — |
case-17 | fail→fail | 5,743 | 4,379 | -24% | 1 | 1 | 0% | 1,013 | 1,830 | +81% | 0 | 0 | — |
case-18 | pass→pass | 4,459 | 4,157 | -7% | 1 | 1 | 0% | 802 | 1,781 | +122% | 0 | 0 | — |
case-19 | fail→pass | 10,227 | 6,071 | -41% | 1 | 1 | 0% | 1,887 | 2,137 | +13% | 0 | 0 | — |
case-20 | pass→fail | 6,614 | 6,825 | +3% | 1 | 1 | 0% | 1,185 | 2,379 | +101% | 0 | 0 | — |
case-21 | fail→pass | 10,235 | 9,743 | -5% | 1 | 1 | 0% | 1,875 | 2,768 | +48% | 0 | 0 | — |
case-22 | pass→pass | 9,234 | 7,097 | -23% | 1 | 1 | 0% | 1,738 | 2,285 | +31% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of -20 percentage points is the difference between those two pass rates over the 22 comparable cases. 3 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.