Rust Development
Covers crates, workspaces, and Rust CLIs. Check Cargo.toml, rust-toolchain.toml, and CI before using newer syntax or APIs. Project conventions win over these defaults.
Version and Features
- Stay within
package.rust-version(MSRV) and the pinned toolchain unless the task is an upgrade. - Use Edition 2024 syntax only when the crate sets
edition = "2024". - Keep features additive. Do not assume
--all-featurescompiles when the crate documents mutually exclusive features.
Defaults
- Stdlib and existing crates first.
thiserrorfor library error enums andanyhowfor application glue only when the crate already uses them or boilerplate justifies it. - Newtypes for IDs, tokens, and validated values; enums for states. Private first, then
pub(crate), thenpub. - Implement
From,TryFrom,AsRef,FromStr, andDisplaybefore ad hoc conversion methods. - Parsing and validation return
Resultwith a typed error.unwrap/expectin production code only with a named local invariant. - When the borrow checker objects, fix the data flow before reaching for
clone(). Use lifetimes in APIs only for real zero-copy needs. - Async only where the runtime or I/O boundary requires it. Never hold a blocking mutex guard across
.await. Bound channels, queues, and retries. - Keep secrets out of
Debugoutput, logs, errors, and snapshots. unsafe: small blocks behind a safe API, a// SAFETY:comment stating the invariant, and focused tests or configured Miri.
Checks
Use the project's configured Cargo commands first. While editing, run focused checks (cargo check -p <crate>, cargo test -p <crate> <name>); before finishing, run the full gates:
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test --all-targets # or cargo nextest run, when the project uses nextest
cargo test --doc # --all-targets and nextest both skip doctests
Test behavior through the public API with valid, invalid, and boundary cases, not private helpers. Never run cargo clean as a routine fix; it throws away the incremental cache.
References
- testing.md: read when adding or reshaping tests, or when the test loop is slow.
- linting.md: read when changing rustfmt, Clippy, or workspace/feature check flags.
Done when the relevant build/test/lint checks pass on what you changed, or you name each check that did not run and why.