SuperAPI AI Directory

rust-best-practices

Coding & development

View repository

Updated 10-15 20:32

About this skill

Rust best practices

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:

  1. cargo fmt
  2. cargo clippy --all-targets -- -D warnings (or the CI default)
  3. cargo test
  4. No TODO/unwrap new 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.
  • match exhaustive; if let only for one relevant arm.
  • Avoid legacy ref ; use modern destructuring.
  • Default, builders, or new functions with clear preconditions.
  • Naming: snake_case, types UpperCamelCase, consts SCREAMING_SNAKE when conventional.
  • Document pub items 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 ; avoid Box<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 &str over &String; &[T] over &Vec<T>.
  • Interior mutability (Cell/RefCell/Mutex) only with reason; document thread-safety (Send/Sync).
  • Avoid clone in 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_used in sensitive areas when the project allows it.

Unsafe

  • Last resort. Every unsafe block with a safety invariant.
  • Encapsulate in a minimal safe API.
  • Do not copy unsafe from Stack Overflow without understanding aliasing/lifetimes.
  • Preferable: audited crates (bytes, zerocopy, etc.) to homemade unsafe .

Concurrency

  • Share with Arc; mutate with Mutex/RwLock or channels.
  • Prefer message passing when it reduces contention.
  • Avoid std::thread::sleep in async; use tokio::time.
  • Detect potential deadlocks (lock ordering).
  • Send/Sync errors: fix the design, do not "escape" with unjustified wrappers.

Dependencies

  • Few, known, maintained.
  • cargo deny / cargo audit when 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 criterion only for real regressions.
  • CI: fmt + clippy + test (+ MSRV if declared).

Smells to eliminate

  • String as a "universal type"
  • mut and reassigns where a new binding would be clearer
  • Modules utils dump
  • 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/pub minimal and documented when external
  • Idiomatic errors; panics only on invariants
  • unsafe absent or encapsulated with invariants
  • Tests cover refactor regressions