| name | rust-best-practices |
| description | Write idiomatic Rust code. Use when writing Rust, reviewing Rust code, or refactoring. Covers ownership patterns, error handling, and performance. |
Rust Best Practices
Error Handling - thiserror vs anyhow
thiserror - Libraries, typed errors for pattern matching
anyhow - Applications, opaque errors with .context() chains
Rule: Libraries export thiserror types, applications convert to anyhow::Error at boundaries.
Don't use Box<dyn Error> - Too generic, use thiserror enums or anyhow instead
Ownership Gotchas
Partial borrows - Borrow specific fields instead of &mut self:
// Bad: Borrows entire struct
fn process(&mut self) {
self.helper(&self.data); // Compile error!
}
// Good: Borrow what you need
fn process(&mut self) {
Self::helper(&mut self.state, &self.data);
}
Overly broad borrowing - &mut self borrows the WHOLE struct, blocks other field access
Anti-Patterns
- Out parameters - Return values instead, Rust has zero-cost returns
- Excessive macros - Prefer functions and traits
- Not covering all match patterns - Always handle exhaustively or use
_ - Unnecessary
.clone()in hot paths - Restructure instead .unwrap()in production - Use ONLY in tests, examples, or truly impossible failures
Type System Idioms
- Newtype pattern - Wrap primitives for type safety:
struct UserId(u64); - Use enums instead of booleans - More expressive:
enum Mode { Read, Write }notis_read: bool - Builder pattern - For structs with many optional fields
Function Parameters
&stroverString- More flexible&[T]over&Vec<T>- Same reasonCow<str>- When you might need to own, delays allocation
Essential Crates (2025)
Serialization: serde
Async runtime: tokio
Web framework: axum
Error handling: thiserror (libs), anyhow (apps)
CLI parsing: clap
HTTP client: reqwest
Logging/tracing: tracing (better than log for async)
Performance
- Profile before optimizing -
cargo flamegraphortokio-console - Use
#[inline]for tiny functions - Especially in library code - Checked arithmetic in release - Enable overflow checks for safety-critical code
Security
- Validate all external input - Never trust user data
- Use
cargo-audit- Check dependencies for vulnerabilities - Minimize
unsafe- Document safety invariants heavily