Rust Best Practices
Comprehensive guide for writing high-quality, idiomatic, and highly optimized Rust code. Contains 179 rules across 14 categories, prioritized by impact to guide LLMs in code generation and refactoring.
When to Apply
Reference these guidelines when:
- Writing new Rust functions, structs, or modules
- Implementing error handling or async code
- Designing public APIs for libraries
- Reviewing code for ownership/borrowing issues
- Optimizing memory usage or reducing allocations
- Tuning performance for hot paths
- Refactoring existing Rust code
Rule Categories by Priority
| Priority |
Category |
Impact |
Prefix |
Rules |
| 1 |
Ownership & Borrowing |
CRITICAL |
own- |
12 |
| 2 |
Error Handling |
CRITICAL |
err- |
12 |
| 3 |
Memory Optimization |
CRITICAL |
mem- |
15 |
| 4 |
API Design |
HIGH |
api- |
15 |
| 5 |
Async/Await |
HIGH |
async- |
15 |
| 6 |
Compiler Optimization |
HIGH |
opt- |
12 |
| 7 |
Naming Conventions |
MEDIUM |
name- |
16 |
| 8 |
Type Safety |
MEDIUM |
type- |
10 |
| 9 |
Testing |
MEDIUM |
test- |
13 |
| 10 |
Documentation |
MEDIUM |
doc- |
11 |
| 11 |
Performance Patterns |
MEDIUM |
perf- |
11 |
| 12 |
Project Structure |
LOW |
proj- |
11 |
| 13 |
Clippy & Linting |
LOW |
lint- |
11 |
| 14 |
Anti-patterns |
REFERENCE |
anti- |
15 |
Quick Reference
1. Ownership & Borrowing (CRITICAL)
own-borrow-over-clone - Prefer &T borrowing over .clone()
own-slice-over-vec - Accept &[T] not &Vec<T>, &str not &String
own-cow-conditional - Use Cow<'a, T> for conditional ownership
own-arc-shared - Use Arc<T> for thread-safe shared ownership
own-rc-single-thread - Use Rc<T> for single-threaded sharing
own-refcell-interior - Use RefCell<T> for interior mutability (single-thread)
own-mutex-interior - Use Mutex<T> for interior mutability (multi-thread)
own-rwlock-readers - Use RwLock<T> when reads dominate writes
own-copy-small - Derive Copy for small, trivial types
own-clone-explicit - Make Clone explicit, avoid implicit copies
own-move-large - Move large data instead of cloning
own-lifetime-elision - Rely on lifetime elision when possible
2. Error Handling (CRITICAL)
err-thiserror-lib - Use thiserror for library error types
err-anyhow-app - Use anyhow for application error handling
err-result-over-panic - Return Result, don't panic on expected errors
err-context-chain - Add context with .context() or .with_context()
err-no-unwrap-prod - Never use .unwrap() in production code
err-expect-bugs-only - Use .expect() only for programming errors
err-question-mark - Use ? operator for clean propagation
err-from-impl - Use #[from] for automatic error conversion
err-source-chain - Use #[source] to chain underlying errors
err-lowercase-msg - Error messages: lowercase, no trailing punctuation
err-doc-errors - Document errors with # Errors section
err-custom-type - Create custom error types, not Box<dyn Error>
3. Memory Optimization (CRITICAL)
mem-with-capacity - Use with_capacity() when size is known
mem-smallvec - Use SmallVec for usually-small collections
mem-arrayvec - Use ArrayVec for bounded-size collections
mem-box-large-variant - Box large enum variants to reduce type size
mem-boxed-slice - Use Box<[T]> instead of Vec<T> when fixed
mem-thinvec - Use ThinVec for often-empty vectors
mem-clone-from - Use clone_from() to reuse allocations
mem-reuse-collections - Reuse collections with clear() in loops
mem-avoid-format - Avoid format!() when string literals work
mem-write-over-format - Use write!() instead of format!()
mem-arena-allocator - Use arena allocators for batch allocations
mem-zero-copy - Use zero-copy patterns with slices and Bytes
mem-compact-string - Use CompactString for small string optimization
mem-smaller-integers - Use smallest integer type that fits
mem-assert-type-size - Assert hot type sizes to prevent regressions
4. API Design (HIGH)
api-builder-pattern - Use Builder pattern for complex construction
api-builder-must-use - Add #[must_use] to builder types
api-newtype-safety - Use newtypes for type-safe distinctions
api-typestate - Use typestate for compile-time state machines
api-sealed-trait - Seal traits to prevent external implementations
api-extension-trait - Use extension traits to add methods to foreign types
api-parse-dont-validate - Parse into validated types at boundaries
api-impl-into - Accept impl Into<T> for flexible string inputs
api-impl-asref - Accept impl AsRef<T> for borrowed inputs
api-must-use - Add #[must_use] to Result returning functions
api-non-exhaustive - Use #[non_exhaustive] for future-proof enums/structs
api-from-not-into - Implement From, not Into (auto-derived)
api-default-impl - Implement Default for sensible defaults
api-common-traits - Implement Debug, Clone, PartialEq eagerly
api-serde-optional - Gate Serialize/Deserialize behind feature flag
5. Async/Await (HIGH)
async-tokio-runtime - Use Tokio for production async runtime
async-no-lock-await - Never hold Mutex/RwLock across .await
async-spawn-blocking - Use spawn_blocking for CPU-intensive work
async-tokio-fs - Use tokio::fs not std::fs in async code
async-cancellation-token - Use CancellationToken for graceful shutdown
async-join-parallel - Use tokio::join! for parallel operations
async-try-join - Use tokio::try_join! for fallible parallel ops
async-select-racing - Use tokio::select! for racing/timeouts
async-bounded-channel - Use bounded channels for backpressure
async-mpsc-queue - Use mpsc for work queues
async-broadcast-pubsub - Use broadcast for pub/sub patterns
async-watch-latest - Use watch for latest-value sharing
async-oneshot-response - Use oneshot for request/response
async-joinset-structured - Use JoinSet for dynamic task groups
async-clone-before-await - Clone data before await, release locks
6. Compiler Optimization (HIGH)
opt-inline-small - Use #[inline] for small hot functions
opt-inline-always-rare - Use #[inline(always)] sparingly
opt-inline-never-cold - Use #[inline(never)] for cold paths
opt-cold-unlikely - Use #[cold] for error/unlikely paths
opt-likely-hint - Use likely()/unlikely() for branch hints
opt-lto-release - Enable LTO in release builds
opt-codegen-units - Use codegen-units = 1 for max optimization
opt-pgo-profile - Use PGO for production builds
opt-target-cpu - Set target-cpu=native for local builds
opt-bounds-check - Use iterators to avoid bounds checks
opt-simd-portable - Use portable SIMD for data-parallel ops
opt-cache-friendly - Design cache-friendly data layouts (SoA)
7. Naming Conventions (MEDIUM)
name-types-camel - Use UpperCamelCase for types, traits, enums
name-variants-camel - Use UpperCamelCase for enum variants
name-funcs-snake - Use snake_case for functions, methods, modules
name-consts-screaming - Use SCREAMING_SNAKE_CASE for constants/statics
name-lifetime-short - Use short lowercase lifetimes: 'a, 'de, 'src
name-type-param-single - Use single uppercase for type params: T, E, K, V
name-as-free - as_ prefix: free reference conversion
name-to-expensive - to_ prefix: expensive conversion
name-into-ownership - into_ prefix: ownership transfer
name-no-get-prefix - No get_ prefix for simple getters
name-is-has-bool - Use is_, has_, can_ for boolean methods
name-iter-convention - Use iter/iter_mut/into_iter for iterators
name-iter-method - Name iterator methods consistently
name-iter-type-match - Iterator type names match method
name-acronym-word - Treat acronyms as words: Uuid not UUID
name-crate-no-rs - Crate names: no -rs suffix
8. Type Safety (MEDIUM)
type-newtype-ids - Wrap IDs in newtypes: UserId(u64)
type-newtype-validated - Newtypes for validated data: Email, Url
type-enum-states - Use enums for mutually exclusive states
type-option-nullable - Use Option<T> for nullable values
type-result-fallible - Use Result<T, E> for fallible operations
type-phantom-marker - Use PhantomData<T> for type-level markers
type-never-diverge - Use ! type for functions that never return
type-generic-bounds - Add trait bounds only where needed
type-no-stringly - Avoid stringly-typed APIs, use enums/newtypes
type-repr-transparent - Use #[repr(transparent)] for FFI newtypes
9. Testing (MEDIUM)
test-cfg-test-module - Use #[cfg(test)] mod tests { }
test-use-super - Use use super::*; in test modules
test-integration-dir - Put integration tests in tests/ directory
test-descriptive-names - Use descriptive test names
test-arrange-act-assert - Structure tests as arrange/act/assert
test-proptest-properties - Use proptest for property-based testing
test-mockall-mocking - Use mockall for trait mocking
test-mock-traits - Use traits for dependencies to enable mocking
test-fixture-raii - Use RAII pattern (Drop) for test cleanup
test-tokio-async - Use #[tokio::test] for async tests
test-should-panic - Use #[should_panic] for panic tests
test-criterion-bench - Use criterion for benchmarking
test-doctest-examples - Keep doc examples as executable tests
10. Documentation (MEDIUM)
doc-all-public - Document all public items with ///
doc-module-inner - Use //! for module-level documentation
doc-examples-section - Include # Examples with runnable code
doc-errors-section - Include # Errors for fallible functions
doc-panics-section - Include # Panics for panicking functions
doc-safety-section - Include # Safety for unsafe functions
doc-question-mark - Use ? in examples, not .unwrap()
doc-hidden-setup - Use # prefix to hide example setup code
doc-intra-links - Use intra-doc links: [Vec]
doc-link-types - Link related types and functions in docs
doc-cargo-metadata - Fill Cargo.toml metadata
11. Performance Patterns (MEDIUM)
perf-iter-over-index - Prefer iterators over manual indexing
perf-iter-lazy - Keep iterators lazy, collect() only when needed
perf-collect-once - Don't collect() intermediate iterators
perf-entry-api - Use entry() API for map insert-or-update
perf-drain-reuse - Use drain() to reuse allocations
perf-extend-batch - Use extend() for batch insertions
perf-chain-avoid - Avoid chain() in hot loops
perf-collect-into - Use collect_into() for reusing containers
perf-black-box-bench - Use black_box() in benchmarks
perf-release-profile - Optimize release profile settings
perf-profile-first - Profile before optimizing
12. Project Structure (LOW)
proj-lib-main-split - Keep main.rs minimal, logic in lib.rs
proj-mod-by-feature - Organize modules by feature, not type
proj-flat-small - Keep small projects flat
proj-mod-rs-dir - Use mod.rs for multi-file modules
proj-pub-crate-internal - Use pub(crate) for internal APIs
proj-pub-super-parent - Use pub(super) for parent-only visibility
proj-pub-use-reexport - Use pub use for clean public API
proj-prelude-module - Create prelude module for common imports
proj-bin-dir - Put multiple binaries in src/bin/
proj-workspace-large - Use workspaces for large projects
proj-workspace-deps - Use workspace dependency inheritance
13. Clippy & Linting (LOW)
lint-deny-correctness - #![deny(clippy::correctness)]
lint-warn-suspicious - #![warn(clippy::suspicious)]
lint-warn-style - #![warn(clippy::style)]
lint-warn-complexity - #![warn(clippy::complexity)]
lint-warn-perf - #![warn(clippy::perf)]
lint-pedantic-selective - Enable clippy::pedantic selectively
lint-missing-docs - #![warn(missing_docs)]
lint-unsafe-doc - #![warn(clippy::undocumented_unsafe_blocks)]
lint-cargo-metadata - #![warn(clippy::cargo)] for published crates
lint-rustfmt-check - Run cargo fmt --check in CI
lint-workspace-lints - Configure lints at workspace level
14. Anti-patterns (REFERENCE)
anti-unwrap-abuse - Don't use .unwrap() in production code
anti-expect-lazy - Don't use .expect() for recoverable errors
anti-clone-excessive - Don't clone when borrowing works
anti-lock-across-await - Don't hold locks across .await
anti-string-for-str - Don't accept &String when &str works
anti-vec-for-slice - Don't accept &Vec<T> when &[T] works
anti-index-over-iter - Don't use indexing when iterators work
anti-panic-expected - Don't panic on expected/recoverable errors
anti-empty-catch - Don't use empty if let Err(_) = ... blocks
anti-over-abstraction - Don't over-abstract with excessive generics
anti-premature-optimize - Don't optimize before profiling
anti-type-erasure - Don't use Box<dyn Trait> when impl Trait works
anti-format-hot-path - Don't use format!() in hot paths
anti-collect-intermediate - Don't collect() intermediate iterators
anti-stringly-typed - Don't use strings for structured data
Recommended Cargo.toml Settings
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
panic = "abort"
strip = true
[profile.bench]
inherits = "release"
debug = true
strip = false
[profile.dev]
opt-level = 0
debug = true
[profile.dev.package."*"]
opt-level = 3 # Optimize dependencies in dev
How to Use
This skill provides rule identifiers for quick reference. When generating or reviewing Rust code:
- Check relevant category based on task type
- Apply rules with matching prefix
- Prioritize CRITICAL > HIGH > MEDIUM > LOW
- Read rule files in
rules/ for detailed examples
Rule Application by Task
| Task |
Primary Categories |
| New function |
own-, err-, name- |
| New struct/API |
api-, type-, doc- |
| Async code |
async-, own- |
| Error handling |
err-, api- |
| Memory optimization |
mem-, own-, perf- |
| Performance tuning |
opt-, mem-, perf- |
| Code review |
anti-, lint- |
Sources
This skill synthesizes best practices from:
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: pythoninthegrasses-lunchjs-rust-skills3description: > Use when this capability is needed.4metadata:5 author: pythoninthegrasses6---78# Rust Best Practices910Comprehensive guide for writing high-quality, idiomatic, and highly optimized Rust code. Contains 179 rules across 14 categories, prioritized by impact to guide LLMs in code generation and refactoring.1112## When to Apply1314Reference these guidelines when:15- Writing new Rust functions, structs, or modules16- Implementing error handling or async code17- Designing public APIs for libraries18- Reviewing code for ownership/borrowing issues19- Optimizing memory usage or reducing allocations20- Tuning performance for hot paths21- Refactoring existing Rust code2223## Rule Categories by Priority2425| Priority | Category | Impact | Prefix | Rules |26|----------|----------|--------|--------|-------|27| 1 | Ownership & Borrowing | CRITICAL | `own-` | 12 |28| 2 | Error Handling | CRITICAL | `err-` | 12 |29| 3 | Memory Optimization | CRITICAL | `mem-` | 15 |30| 4 | API Design | HIGH | `api-` | 15 |31| 5 | Async/Await | HIGH | `async-` | 15 |32| 6 | Compiler Optimization | HIGH | `opt-` | 12 |33| 7 | Naming Conventions | MEDIUM | `name-` | 16 |34| 8 | Type Safety | MEDIUM | `type-` | 10 |35| 9 | Testing | MEDIUM | `test-` | 13 |36| 10 | Documentation | MEDIUM | `doc-` | 11 |37| 11 | Performance Patterns | MEDIUM | `perf-` | 11 |38| 12 | Project Structure | LOW | `proj-` | 11 |39| 13 | Clippy & Linting | LOW | `lint-` | 11 |40| 14 | Anti-patterns | REFERENCE | `anti-` | 15 |4142---4344## Quick Reference4546### 1. Ownership & Borrowing (CRITICAL)4748- [`own-borrow-over-clone`](rules/own-borrow-over-clone.md) - Prefer `&T` borrowing over `.clone()`49- [`own-slice-over-vec`](rules/own-slice-over-vec.md) - Accept `&[T]` not `&Vec<T>`, `&str` not `&String`50- [`own-cow-conditional`](rules/own-cow-conditional.md) - Use `Cow<'a, T>` for conditional ownership51- [`own-arc-shared`](rules/own-arc-shared.md) - Use `Arc<T>` for thread-safe shared ownership52- [`own-rc-single-thread`](rules/own-rc-single-thread.md) - Use `Rc<T>` for single-threaded sharing53- [`own-refcell-interior`](rules/own-refcell-interior.md) - Use `RefCell<T>` for interior mutability (single-thread)54- [`own-mutex-interior`](rules/own-mutex-interior.md) - Use `Mutex<T>` for interior mutability (multi-thread)55- [`own-rwlock-readers`](rules/own-rwlock-readers.md) - Use `RwLock<T>` when reads dominate writes56- [`own-copy-small`](rules/own-copy-small.md) - Derive `Copy` for small, trivial types57- [`own-clone-explicit`](rules/own-clone-explicit.md) - Make `Clone` explicit, avoid implicit copies58- [`own-move-large`](rules/own-move-large.md) - Move large data instead of cloning59- [`own-lifetime-elision`](rules/own-lifetime-elision.md) - Rely on lifetime elision when possible6061### 2. Error Handling (CRITICAL)6263- [`err-thiserror-lib`](rules/err-thiserror-lib.md) - Use `thiserror` for library error types64- [`err-anyhow-app`](rules/err-anyhow-app.md) - Use `anyhow` for application error handling65- [`err-result-over-panic`](rules/err-result-over-panic.md) - Return `Result`, don't panic on expected errors66- [`err-context-chain`](rules/err-context-chain.md) - Add context with `.context()` or `.with_context()`67- [`err-no-unwrap-prod`](rules/err-no-unwrap-prod.md) - Never use `.unwrap()` in production code68- [`err-expect-bugs-only`](rules/err-expect-bugs-only.md) - Use `.expect()` only for programming errors69- [`err-question-mark`](rules/err-question-mark.md) - Use `?` operator for clean propagation70- [`err-from-impl`](rules/err-from-impl.md) - Use `#[from]` for automatic error conversion71- [`err-source-chain`](rules/err-source-chain.md) - Use `#[source]` to chain underlying errors72- [`err-lowercase-msg`](rules/err-lowercase-msg.md) - Error messages: lowercase, no trailing punctuation73- [`err-doc-errors`](rules/err-doc-errors.md) - Document errors with `# Errors` section74- [`err-custom-type`](rules/err-custom-type.md) - Create custom error types, not `Box<dyn Error>`7576### 3. Memory Optimization (CRITICAL)7778- [`mem-with-capacity`](rules/mem-with-capacity.md) - Use `with_capacity()` when size is known79- [`mem-smallvec`](rules/mem-smallvec.md) - Use `SmallVec` for usually-small collections80- [`mem-arrayvec`](rules/mem-arrayvec.md) - Use `ArrayVec` for bounded-size collections81- [`mem-box-large-variant`](rules/mem-box-large-variant.md) - Box large enum variants to reduce type size82- [`mem-boxed-slice`](rules/mem-boxed-slice.md) - Use `Box<[T]>` instead of `Vec<T>` when fixed83- [`mem-thinvec`](rules/mem-thinvec.md) - Use `ThinVec` for often-empty vectors84- [`mem-clone-from`](rules/mem-clone-from.md) - Use `clone_from()` to reuse allocations85- [`mem-reuse-collections`](rules/mem-reuse-collections.md) - Reuse collections with `clear()` in loops86- [`mem-avoid-format`](rules/mem-avoid-format.md) - Avoid `format!()` when string literals work87- [`mem-write-over-format`](rules/mem-write-over-format.md) - Use `write!()` instead of `format!()` 88- [`mem-arena-allocator`](rules/mem-arena-allocator.md) - Use arena allocators for batch allocations89- [`mem-zero-copy`](rules/mem-zero-copy.md) - Use zero-copy patterns with slices and `Bytes`90- [`mem-compact-string`](rules/mem-compact-string.md) - Use `CompactString` for small string optimization91- [`mem-smaller-integers`](rules/mem-smaller-integers.md) - Use smallest integer type that fits92- [`mem-assert-type-size`](rules/mem-assert-type-size.md) - Assert hot type sizes to prevent regressions9394### 4. API Design (HIGH)9596- [`api-builder-pattern`](rules/api-builder-pattern.md) - Use Builder pattern for complex construction97- [`api-builder-must-use`](rules/api-builder-must-use.md) - Add `#[must_use]` to builder types98- [`api-newtype-safety`](rules/api-newtype-safety.md) - Use newtypes for type-safe distinctions99- [`api-typestate`](rules/api-typestate.md) - Use typestate for compile-time state machines100- [`api-sealed-trait`](rules/api-sealed-trait.md) - Seal traits to prevent external implementations101- [`api-extension-trait`](rules/api-extension-trait.md) - Use extension traits to add methods to foreign types102- [`api-parse-dont-validate`](rules/api-parse-dont-validate.md) - Parse into validated types at boundaries103- [`api-impl-into`](rules/api-impl-into.md) - Accept `impl Into<T>` for flexible string inputs104- [`api-impl-asref`](rules/api-impl-asref.md) - Accept `impl AsRef<T>` for borrowed inputs105- [`api-must-use`](rules/api-must-use.md) - Add `#[must_use]` to `Result` returning functions106- [`api-non-exhaustive`](rules/api-non-exhaustive.md) - Use `#[non_exhaustive]` for future-proof enums/structs107- [`api-from-not-into`](rules/api-from-not-into.md) - Implement `From`, not `Into` (auto-derived)108- [`api-default-impl`](rules/api-default-impl.md) - Implement `Default` for sensible defaults109- [`api-common-traits`](rules/api-common-traits.md) - Implement `Debug`, `Clone`, `PartialEq` eagerly110- [`api-serde-optional`](rules/api-serde-optional.md) - Gate `Serialize`/`Deserialize` behind feature flag111112### 5. Async/Await (HIGH)113114- [`async-tokio-runtime`](rules/async-tokio-runtime.md) - Use Tokio for production async runtime115- [`async-no-lock-await`](rules/async-no-lock-await.md) - Never hold `Mutex`/`RwLock` across `.await`116- [`async-spawn-blocking`](rules/async-spawn-blocking.md) - Use `spawn_blocking` for CPU-intensive work117- [`async-tokio-fs`](rules/async-tokio-fs.md) - Use `tokio::fs` not `std::fs` in async code118- [`async-cancellation-token`](rules/async-cancellation-token.md) - Use `CancellationToken` for graceful shutdown119- [`async-join-parallel`](rules/async-join-parallel.md) - Use `tokio::join!` for parallel operations120- [`async-try-join`](rules/async-try-join.md) - Use `tokio::try_join!` for fallible parallel ops121- [`async-select-racing`](rules/async-select-racing.md) - Use `tokio::select!` for racing/timeouts122- [`async-bounded-channel`](rules/async-bounded-channel.md) - Use bounded channels for backpressure123- [`async-mpsc-queue`](rules/async-mpsc-queue.md) - Use `mpsc` for work queues124- [`async-broadcast-pubsub`](rules/async-broadcast-pubsub.md) - Use `broadcast` for pub/sub patterns125- [`async-watch-latest`](rules/async-watch-latest.md) - Use `watch` for latest-value sharing126- [`async-oneshot-response`](rules/async-oneshot-response.md) - Use `oneshot` for request/response127- [`async-joinset-structured`](rules/async-joinset-structured.md) - Use `JoinSet` for dynamic task groups128- [`async-clone-before-await`](rules/async-clone-before-await.md) - Clone data before await, release locks129130### 6. Compiler Optimization (HIGH)131132- [`opt-inline-small`](rules/opt-inline-small.md) - Use `#[inline]` for small hot functions133- [`opt-inline-always-rare`](rules/opt-inline-always-rare.md) - Use `#[inline(always)]` sparingly134- [`opt-inline-never-cold`](rules/opt-inline-never-cold.md) - Use `#[inline(never)]` for cold paths135- [`opt-cold-unlikely`](rules/opt-cold-unlikely.md) - Use `#[cold]` for error/unlikely paths136- [`opt-likely-hint`](rules/opt-likely-hint.md) - Use `likely()`/`unlikely()` for branch hints137- [`opt-lto-release`](rules/opt-lto-release.md) - Enable LTO in release builds138- [`opt-codegen-units`](rules/opt-codegen-units.md) - Use `codegen-units = 1` for max optimization139- [`opt-pgo-profile`](rules/opt-pgo-profile.md) - Use PGO for production builds140- [`opt-target-cpu`](rules/opt-target-cpu.md) - Set `target-cpu=native` for local builds141- [`opt-bounds-check`](rules/opt-bounds-check.md) - Use iterators to avoid bounds checks142- [`opt-simd-portable`](rules/opt-simd-portable.md) - Use portable SIMD for data-parallel ops143- [`opt-cache-friendly`](rules/opt-cache-friendly.md) - Design cache-friendly data layouts (SoA)144145### 7. Naming Conventions (MEDIUM)146147- [`name-types-camel`](rules/name-types-camel.md) - Use `UpperCamelCase` for types, traits, enums148- [`name-variants-camel`](rules/name-variants-camel.md) - Use `UpperCamelCase` for enum variants149- [`name-funcs-snake`](rules/name-funcs-snake.md) - Use `snake_case` for functions, methods, modules150- [`name-consts-screaming`](rules/name-consts-screaming.md) - Use `SCREAMING_SNAKE_CASE` for constants/statics151- [`name-lifetime-short`](rules/name-lifetime-short.md) - Use short lowercase lifetimes: `'a`, `'de`, `'src`152- [`name-type-param-single`](rules/name-type-param-single.md) - Use single uppercase for type params: `T`, `E`, `K`, `V`153- [`name-as-free`](rules/name-as-free.md) - `as_` prefix: free reference conversion154- [`name-to-expensive`](rules/name-to-expensive.md) - `to_` prefix: expensive conversion155- [`name-into-ownership`](rules/name-into-ownership.md) - `into_` prefix: ownership transfer156- [`name-no-get-prefix`](rules/name-no-get-prefix.md) - No `get_` prefix for simple getters157- [`name-is-has-bool`](rules/name-is-has-bool.md) - Use `is_`, `has_`, `can_` for boolean methods158- [`name-iter-convention`](rules/name-iter-convention.md) - Use `iter`/`iter_mut`/`into_iter` for iterators159- [`name-iter-method`](rules/name-iter-method.md) - Name iterator methods consistently160- [`name-iter-type-match`](rules/name-iter-type-match.md) - Iterator type names match method161- [`name-acronym-word`](rules/name-acronym-word.md) - Treat acronyms as words: `Uuid` not `UUID`162- [`name-crate-no-rs`](rules/name-crate-no-rs.md) - Crate names: no `-rs` suffix163164### 8. Type Safety (MEDIUM)165166- [`type-newtype-ids`](rules/type-newtype-ids.md) - Wrap IDs in newtypes: `UserId(u64)`167- [`type-newtype-validated`](rules/type-newtype-validated.md) - Newtypes for validated data: `Email`, `Url`168- [`type-enum-states`](rules/type-enum-states.md) - Use enums for mutually exclusive states169- [`type-option-nullable`](rules/type-option-nullable.md) - Use `Option<T>` for nullable values170- [`type-result-fallible`](rules/type-result-fallible.md) - Use `Result<T, E>` for fallible operations171- [`type-phantom-marker`](rules/type-phantom-marker.md) - Use `PhantomData<T>` for type-level markers172- [`type-never-diverge`](rules/type-never-diverge.md) - Use `!` type for functions that never return173- [`type-generic-bounds`](rules/type-generic-bounds.md) - Add trait bounds only where needed174- [`type-no-stringly`](rules/type-no-stringly.md) - Avoid stringly-typed APIs, use enums/newtypes175- [`type-repr-transparent`](rules/type-repr-transparent.md) - Use `#[repr(transparent)]` for FFI newtypes176177### 9. Testing (MEDIUM)178179- [`test-cfg-test-module`](rules/test-cfg-test-module.md) - Use `#[cfg(test)] mod tests { }`180- [`test-use-super`](rules/test-use-super.md) - Use `use super::*;` in test modules181- [`test-integration-dir`](rules/test-integration-dir.md) - Put integration tests in `tests/` directory182- [`test-descriptive-names`](rules/test-descriptive-names.md) - Use descriptive test names183- [`test-arrange-act-assert`](rules/test-arrange-act-assert.md) - Structure tests as arrange/act/assert184- [`test-proptest-properties`](rules/test-proptest-properties.md) - Use `proptest` for property-based testing185- [`test-mockall-mocking`](rules/test-mockall-mocking.md) - Use `mockall` for trait mocking186- [`test-mock-traits`](rules/test-mock-traits.md) - Use traits for dependencies to enable mocking187- [`test-fixture-raii`](rules/test-fixture-raii.md) - Use RAII pattern (Drop) for test cleanup188- [`test-tokio-async`](rules/test-tokio-async.md) - Use `#[tokio::test]` for async tests189- [`test-should-panic`](rules/test-should-panic.md) - Use `#[should_panic]` for panic tests190- [`test-criterion-bench`](rules/test-criterion-bench.md) - Use `criterion` for benchmarking191- [`test-doctest-examples`](rules/test-doctest-examples.md) - Keep doc examples as executable tests192193### 10. Documentation (MEDIUM)194195- [`doc-all-public`](rules/doc-all-public.md) - Document all public items with `///`196- [`doc-module-inner`](rules/doc-module-inner.md) - Use `//!` for module-level documentation197- [`doc-examples-section`](rules/doc-examples-section.md) - Include `# Examples` with runnable code198- [`doc-errors-section`](rules/doc-errors-section.md) - Include `# Errors` for fallible functions199- [`doc-panics-section`](rules/doc-panics-section.md) - Include `# Panics` for panicking functions200- [`doc-safety-section`](rules/doc-safety-section.md) - Include `# Safety` for unsafe functions201- [`doc-question-mark`](rules/doc-question-mark.md) - Use `?` in examples, not `.unwrap()`202- [`doc-hidden-setup`](rules/doc-hidden-setup.md) - Use `# ` prefix to hide example setup code203- [`doc-intra-links`](rules/doc-intra-links.md) - Use intra-doc links: `[Vec]`204- [`doc-link-types`](rules/doc-link-types.md) - Link related types and functions in docs205- [`doc-cargo-metadata`](rules/doc-cargo-metadata.md) - Fill `Cargo.toml` metadata206207### 11. Performance Patterns (MEDIUM)208209- [`perf-iter-over-index`](rules/perf-iter-over-index.md) - Prefer iterators over manual indexing210- [`perf-iter-lazy`](rules/perf-iter-lazy.md) - Keep iterators lazy, collect() only when needed211- [`perf-collect-once`](rules/perf-collect-once.md) - Don't `collect()` intermediate iterators212- [`perf-entry-api`](rules/perf-entry-api.md) - Use `entry()` API for map insert-or-update213- [`perf-drain-reuse`](rules/perf-drain-reuse.md) - Use `drain()` to reuse allocations214- [`perf-extend-batch`](rules/perf-extend-batch.md) - Use `extend()` for batch insertions215- [`perf-chain-avoid`](rules/perf-chain-avoid.md) - Avoid `chain()` in hot loops216- [`perf-collect-into`](rules/perf-collect-into.md) - Use `collect_into()` for reusing containers217- [`perf-black-box-bench`](rules/perf-black-box-bench.md) - Use `black_box()` in benchmarks218- [`perf-release-profile`](rules/perf-release-profile.md) - Optimize release profile settings219- [`perf-profile-first`](rules/perf-profile-first.md) - Profile before optimizing220221### 12. Project Structure (LOW)222223- [`proj-lib-main-split`](rules/proj-lib-main-split.md) - Keep `main.rs` minimal, logic in `lib.rs`224- [`proj-mod-by-feature`](rules/proj-mod-by-feature.md) - Organize modules by feature, not type225- [`proj-flat-small`](rules/proj-flat-small.md) - Keep small projects flat226- [`proj-mod-rs-dir`](rules/proj-mod-rs-dir.md) - Use `mod.rs` for multi-file modules227- [`proj-pub-crate-internal`](rules/proj-pub-crate-internal.md) - Use `pub(crate)` for internal APIs228- [`proj-pub-super-parent`](rules/proj-pub-super-parent.md) - Use `pub(super)` for parent-only visibility229- [`proj-pub-use-reexport`](rules/proj-pub-use-reexport.md) - Use `pub use` for clean public API230- [`proj-prelude-module`](rules/proj-prelude-module.md) - Create `prelude` module for common imports231- [`proj-bin-dir`](rules/proj-bin-dir.md) - Put multiple binaries in `src/bin/`232- [`proj-workspace-large`](rules/proj-workspace-large.md) - Use workspaces for large projects233- [`proj-workspace-deps`](rules/proj-workspace-deps.md) - Use workspace dependency inheritance234235### 13. Clippy & Linting (LOW)236237- [`lint-deny-correctness`](rules/lint-deny-correctness.md) - `#![deny(clippy::correctness)]`238- [`lint-warn-suspicious`](rules/lint-warn-suspicious.md) - `#![warn(clippy::suspicious)]`239- [`lint-warn-style`](rules/lint-warn-style.md) - `#![warn(clippy::style)]`240- [`lint-warn-complexity`](rules/lint-warn-complexity.md) - `#![warn(clippy::complexity)]`241- [`lint-warn-perf`](rules/lint-warn-perf.md) - `#![warn(clippy::perf)]`242- [`lint-pedantic-selective`](rules/lint-pedantic-selective.md) - Enable `clippy::pedantic` selectively243- [`lint-missing-docs`](rules/lint-missing-docs.md) - `#![warn(missing_docs)]`244- [`lint-unsafe-doc`](rules/lint-unsafe-doc.md) - `#![warn(clippy::undocumented_unsafe_blocks)]`245- [`lint-cargo-metadata`](rules/lint-cargo-metadata.md) - `#![warn(clippy::cargo)]` for published crates246- [`lint-rustfmt-check`](rules/lint-rustfmt-check.md) - Run `cargo fmt --check` in CI247- [`lint-workspace-lints`](rules/lint-workspace-lints.md) - Configure lints at workspace level248249### 14. Anti-patterns (REFERENCE)250251- [`anti-unwrap-abuse`](rules/anti-unwrap-abuse.md) - Don't use `.unwrap()` in production code252- [`anti-expect-lazy`](rules/anti-expect-lazy.md) - Don't use `.expect()` for recoverable errors253- [`anti-clone-excessive`](rules/anti-clone-excessive.md) - Don't clone when borrowing works254- [`anti-lock-across-await`](rules/anti-lock-across-await.md) - Don't hold locks across `.await`255- [`anti-string-for-str`](rules/anti-string-for-str.md) - Don't accept `&String` when `&str` works256- [`anti-vec-for-slice`](rules/anti-vec-for-slice.md) - Don't accept `&Vec<T>` when `&[T]` works257- [`anti-index-over-iter`](rules/anti-index-over-iter.md) - Don't use indexing when iterators work258- [`anti-panic-expected`](rules/anti-panic-expected.md) - Don't panic on expected/recoverable errors259- [`anti-empty-catch`](rules/anti-empty-catch.md) - Don't use empty `if let Err(_) = ...` blocks260- [`anti-over-abstraction`](rules/anti-over-abstraction.md) - Don't over-abstract with excessive generics261- [`anti-premature-optimize`](rules/anti-premature-optimize.md) - Don't optimize before profiling262- [`anti-type-erasure`](rules/anti-type-erasure.md) - Don't use `Box<dyn Trait>` when `impl Trait` works263- [`anti-format-hot-path`](rules/anti-format-hot-path.md) - Don't use `format!()` in hot paths264- [`anti-collect-intermediate`](rules/anti-collect-intermediate.md) - Don't `collect()` intermediate iterators265- [`anti-stringly-typed`](rules/anti-stringly-typed.md) - Don't use strings for structured data266267---268269## Recommended Cargo.toml Settings270271```toml272[profile.release]273opt-level = 3274lto = "fat"275codegen-units = 1276panic = "abort"277strip = true278279[profile.bench]280inherits = "release"281debug = true282strip = false283284[profile.dev]285opt-level = 0286debug = true287288[profile.dev.package."*"]289opt-level = 3 # Optimize dependencies in dev290```291292---293294## How to Use295296This skill provides rule identifiers for quick reference. When generating or reviewing Rust code:2972981. **Check relevant category** based on task type2992. **Apply rules** with matching prefix3003. **Prioritize** CRITICAL > HIGH > MEDIUM > LOW3014. **Read rule files** in `rules/` for detailed examples302303### Rule Application by Task304305| Task | Primary Categories |306|------|-------------------|307| New function | `own-`, `err-`, `name-` |308| New struct/API | `api-`, `type-`, `doc-` |309| Async code | `async-`, `own-` |310| Error handling | `err-`, `api-` |311| Memory optimization | `mem-`, `own-`, `perf-` |312| Performance tuning | `opt-`, `mem-`, `perf-` |313| Code review | `anti-`, `lint-` |314315---316317## Sources318319This skill synthesizes best practices from:320- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)321- [Rust Performance Book](https://nnethercote.github.io/perf-book/)322- [Rust Design Patterns](https://rust-unofficial.github.io/patterns/)323- Production codebases: ripgrep, tokio, serde, polars, axum, deno324- Clippy lint documentation325- Community conventions (2024-2025)326327---328> Converted and distributed by [TomeVault](https://tomevault.io/claim/pythoninthegrasses) — claim your Tome and manage your conversions.329<!-- tomevault:4.0:skill_md:2026-04-13 -->