This skill sharpens quality and idioms. For language fundamentals use rust; for Axum use axum / rust-axum-production.
Continuous checklist
In every PR/scope touched:
cargo fmtcargo clippy --all-targets -- -D warnings(or the CI default)cargo test- No
TODO/unwrapnew without tracking
Treat warnings as errors in new code.
Idioms
- “Parse, don’t validate”: convert input into valid types early.
- Prefer clear iterators and combinators over manual indices when readable.
matchexhaustive;if letonly for one relevant arm.- Avoid legacy
ref; use modern destructuring. Default, builders, ornewfunctions with clear preconditions.- Naming:
snake_case, typesUpperCamelCase, constsSCREAMING_SNAKEwhen conventional. - Document
pubitems with///and examples when the API is external.
API design (crates/libs)
- Minimize surface
pub. - Conscious breaking changes in semver; Cargo features for optional ones.
- Accept
impl AsRef<Path>/impl Into<String>only when real ergonomics are worth the complexity. - Return concrete or stable
impl Trait; avoidBox<dyn Error>in public libs if you can type it. - Do not expose internal dependency types unnecessarily (avoids semver coupling).
#[non_exhaustive]on public enums/structs that may grow.
Idiomatic ownership
- API that needs to store data: accept
impl Into<T>or clear ownership, not&String. - Prefer
&strover&String;&[T]over&Vec<T>. - Interior mutability (
Cell/RefCell/Mutex) only with reason; document thread-safety (Send/Sync). - Avoid
clonein hot paths; measure before micro-optimizing.
Errors and panics
| Context | Preference |
|---|---|
| Lib | thiserror, enum errors |
| App edge | anyhow / eyre if already adopted |
| Internal invariant | expect with a message that states the invariant |
| External input | Result, never panic |
- Chain context; do not discard
source. clippy::unwrap_used/expect_usedin sensitive areas when the project allows it.
Unsafe
- Last resort. Every
unsafeblock with a safety invariant. - Encapsulate in a minimal safe API.
- Do not copy
unsafefrom Stack Overflow without understanding aliasing/lifetimes. - Preferable: audited crates (
bytes,zerocopy, etc.) to homemadeunsafe.
Concurrency
- Share with
Arc; mutate withMutex/RwLockor channels. - Prefer message passing when it reduces contention.
- Avoid
std::thread::sleepin async; usetokio::time. - Detect potential deadlocks (lock ordering).
Send/Syncerrors: fix the design, do not "escape" with unjustified wrappers.
Dependencies
- Few, known, maintained.
cargo deny/cargo auditwhen the repo already uses it; otherwise, audit critical upgrades.- Feature flags: enable only what is necessary (
rt-multi-thread, TLS stack, etc.). - Avoid duplicating semantic crates (two JSON parsers, two TLS).
Tests and quality
- Unit + integration; property tests (
proptest) for parsers/invariants. - Snapshot tests only if the team already uses them and snapshots are reviewed.
- Benches with
criteriononly for real regressions. - CI: fmt + clippy + test (+ MSRV if declared).
Smells to eliminate
Stringas a "universal type"mutand reassigns where a new binding would be clearer- Modules
utilsdump - Comments that narrate the obvious instead of invariants
#[allow(clippy::...)]broad without justification- Commented-out code "just in case"
Completion criteria
- Clippy clean in scope (or justified local allows)
- API/
pubminimal and documented when external - Idiomatic errors; panics only on invariants
unsafeabsent or encapsulated with invariants- Tests cover refactor regressions