Rust Conventions
Idioms
- •Prefer iterators and combinators over explicit loops
- •Use the
?operator for error propagation — avoid manualmatchonResult - •Prefer
impl Traitin return position for complex return types - •Derive
Debug,Clone,PartialEqon most types; addEq,Hashwhen useful - •Prefer owned types (
String,Vec<T>) in public API signatures - •Use
From/Intoconversions instead of manual transformation functions - •Prefer
&strover&Stringin function parameters - •Use
Defaulttrait for structs with sensible defaults
Project Structure
- •Standard Cargo layout:
src/lib.rsorsrc/main.rsat root - •Use workspaces (
Cargo.tomlwith[workspace]) for multi-crate projects - •Feature flags for optional functionality — keep the default feature set minimal
- •
examples/directory for runnable examples - •
benches/directory for benchmarks using criterion
Testing
- •Use built-in
#[cfg(test)]modules for unit tests in the same file - •Integration tests go in
tests/directory at crate root - •Use
proptestfor property-based testing of pure logic - •Prefer
assert_eq!andassert!— useassert_matches!for enum variants - •Test error cases explicitly — ensure
Result::Errpaths are covered - •Use
#[should_panic]sparingly; prefer testingResultreturns
Error Handling
- •Use
thiserrorfor library error types — derive structured, typed errors - •Use
anyhowfor application-level error handling - •Never use
.unwrap()or.expect()in production paths - •
.unwrap()is acceptable in tests and examples - •Define one error enum per module or domain boundary
- •Implement
Displayfor all error types viathiserror
Dependencies
- •Serialization: serde + serde_json
- •Async runtime: tokio (with only needed features enabled)
- •CLI: clap with derive macros
- •Logging/tracing: tracing + tracing-subscriber
- •HTTP: reqwest (client), axum (server)
- •Testing: proptest, assert_matches
Anti-patterns
- •Excessive
.clone()to appease the borrow checker — restructure ownership instead - •Stringly-typed APIs — use enums and newtypes
- •Ignoring clippy lints — run
cargo clippyand address warnings - •
unsafewithout a safety comment and clear justification - •Large functions — decompose into smaller, testable units
- •Using
Box<dyn Error>when a proper error enum is feasible