CLAUDE.md — Rust Project
Project Basics
This is a Rust project using edition 2021. All code must pass cargo clippy -- -D warnings and cargo fmt --check. Prefer safe Rust — avoid unsafe unless absolutely necessary and document safety invariants.
Error Handling
- Libraries: use
thiserrorfor custom error types with#[derive(Error)] - Applications: use
anyhow::Resultfor convenient error propagation - Never use
.unwrap()or.expect()in production code paths — use?operator .unwrap()is acceptable only in tests and examples- Map errors with context:
.context("failed to parse config")?(anyhow) or.map_err() - Define error enums for each module’s public API
Types & Ownership
- Prefer borrowing (
&T,&mut T) over cloning — clone only when ownership transfer is needed - Use
Cow<'_, str>when a function might or might not need to own the string - Lifetimes only when the compiler requires them — don’t annotate unnecessarily
- Newtype pattern for domain types:
struct UserId(u64)instead of rawu64 - Derive
Debugon all types. DeriveClone,PartialEq,Eq,Hashwhen appropriate - Prefer
impl Into<T>orimpl AsRef<T>for flexible function signatures
Naming Conventions
snake_casefor functions, methods, variables, modules, and filesCamelCasefor types, traits, and enumsSCREAMING_SNAKE_CASEfor constants and statics- Modules match file names:
mod authlives inauth.rsorauth/mod.rs - Trait names describe capability:
Serialize,Display,Into
Testing
- Unit tests in the same file:
#[cfg(test)] mod tests { ... } - Integration tests in
tests/directory - Use
#[test]for standard tests,#[tokio::test]for async tests - Property-based testing with
proptestfor complex invariants - Snapshot testing with
instafor complex output validation - Run
cargo testbefore every commit
Dependencies
- Minimize dependencies — each one adds compile time and attack surface
- Check crate maintenance status and download counts before adding
- Use
cargo-denyto audit licenses and security advisories - Pin minor versions in
Cargo.toml:serde = "1.0"notserde = "*" - Run
cargo updateperiodically and test after updating
Unsafe Code
- Avoid
unsafeunless there is no safe alternative and the performance benefit is measurable - Every
unsafeblock must have a// SAFETY:comment explaining why it’s sound - Encapsulate
unsafebehind safe abstractions - Test
unsafecode with Miri when possible:cargo +nightly miri test
Performance
- Always benchmark with release builds:
cargo bench(never debug builds) - Use
criterionfor benchmarks, not manual timing - Don’t optimize prematurely — profile first with
cargo flamegraphorperf - Prefer iterators over manual loops — they optimize better
Build & Deploy
- Release builds:
cargo build --release - Strip symbols for smaller binaries:
[profile.release] strip = trueinCargo.toml - Cross-compilation with
crossorcargo-zigbuild - Static linking with
target-feature=+crt-staticfor portable Linux binaries
Verification
cargo check— compiles without errorscargo test— all tests passcargo clippy -- -D warnings— no lint warningscargo fmt --check— properly formattedcargo doc --no-deps— documentation builds without warnings
Git & GitHub
- Do not push code or create PRs without explicit permission
- Do not perform destructive or irreversible git operations without asking first
- Run the full verification suite before committing