Idiomatic Rust Rubric

Idiomatic Rust rubric

What "idiomatic Rust" actually means when you have to audit a real codebase against it, not vibe about it. I built one of these for Spotuify (14 crates) and ran the same play again on Mxr (26 crates), and the useful realisation is that most of the standard is already written down by other people. A good rubric stitches three existing sources together and adds a policy for what to ignore.

The three sources a rubric is made of

  1. The Rust API Guidelines (rust-lang.github.io/api-guidelines). The C-* checklist is the backbone: naming (RFC 430 casing, as_/to_/into_ conversion costs, getters without get_), interoperability (eager Debug/Clone derives, From/TryFrom over bespoke to_x, error types that impl Error), predictability, type safety (newtypes, no bare-bool args), future-proofing (#[non_exhaustive], private fields). You don't invent these; you cite them.
  2. Clippy lint groups. This is the machine-enforced half. The catch is that "idiomatic" is not "passes every lint" — see Idiomatic Is Not Pedantic-Clean. The rubric has to declare which lints it enforces and which it deliberately allows, or it drowns you.
  3. The project's own non-negotiables. Every codebase has a few rules that aren't in any general guide: spotuify's "every external op has a bounded timeout," "daemon owns state, clients are views," "mutations are dry-run-first." A rubric that ignores these scores the wrong thing.

Sources 1 and 2 are the scoreable backbone. Source 3 is the pass/fail policy layer on top.

The dimensions worth scoring

Not all of the C-* checklist earns its keep for an internal app. The dimensions that actually catch problems:

How to actually run it

Don't read 14 crates by hand. Fan out: parallel agents read the code while a background clippy --workspace --all-targets -W clippy::pedantic -W clippy::nursery produces the objective list. Then cross-reference. The qualitative review catches structure and API design that clippy can't; clippy catches the mechanical stuff the humans skim past. Neither alone is enough.

Score each crate pass/partial/fail per dimension. The weak cells cluster — for spotuify it was structure (a 1190-line dispatch function) and a couple of async-blocking spots, never safety or correctness.

The part people get wrong

A rubric is a license to not change most of what it flags. The 2000-warning pedantic sweep is mostly noise; the god-function rewrite is real but high-risk. A good rubric ranks findings by signal and pairs each refactor with a way to prove it didn't break anything (Refactor Behind a Behavior Test). The findings you do fix should then be ratcheted into [workspace.lints] so they can't silently come back (Ratchet Lints Into the Build). Without that discipline, "make it idiomatic" becomes a giant unreviewable diff, which is the opposite of what the standard is for.

See also