--- description: General Rust rules for safe, idiomatic application and library development globs: ["**/*.rs", "Cargo.toml", "Cargo.lock"] alwaysApply: false --- # Rust General Rules ## Project Structure - Keep crates focused and name modules by domain responsibility. - Put reusable library code in `src/lib.rs` and binary entry points in `src/main.rs` or `src/bin/`. - Keep public APIs small and documented. - Use feature flags deliberately and document non-default features. - Commit `Cargo.lock` for applications; follow the project convention for libraries. ## Ownership and Types - Prefer borrowing over cloning when ownership is not needed. - Use owned values at API boundaries when the callee must store data. - Model domain states with enums and structs instead of strings or booleans. - Use `Option` for absence and `Result` for fallible operations. - Avoid `unwrap()` and `expect()` outside tests, examples, and process-startup invariants. ## Error Handling - Use `thiserror` or project-standard custom errors for libraries. - Use `anyhow` or project-standard context-rich errors for applications. - Add context when crossing IO, network, database, or parsing boundaries. - Do not discard errors with `_` unless explicitly documented. ## Concurrency and Async - Use `Send` and `Sync` boundaries intentionally. - Prefer message passing or owned task inputs for async work. - Do not hold blocking locks across `.await`. - Use `tokio::task::spawn_blocking` or equivalent for blocking CPU or IO in async applications. - Propagate cancellation through futures rather than hiding it in detached tasks. ## Testing and Quality - Run `cargo fmt` and `cargo clippy` before delivery. - Add unit tests for pure logic and integration tests for public behavior. - Use property tests for parsers, serializers, and state machines when useful. - Use benchmarks only after identifying a real performance question. ## Common Mistakes - Do not fight the borrow checker by adding unnecessary `Arc>`. - Do not expose internal module structure through public APIs by accident. - Do not allocate in hot loops without measuring. - Do not use unsafe code unless the invariant is documented and tested.