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-mt-rust-skills3description: Rust Best Practices4---56# Rust Best Practices78Comprehensive 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.910## When to Apply1112Reference these guidelines when:13- Writing new Rust functions, structs, or modules14- Implementing error handling or async code15- Designing public APIs for libraries16- Reviewing code for ownership/borrowing issues17- Optimizing memory usage or reducing allocations18- Tuning performance for hot paths19- Refactoring existing Rust code2021## Rule Categories by Priority2223| Priority | Category | Impact | Prefix | Rules |24|----------|----------|--------|--------|-------|25| 1 | Ownership & Borrowing | CRITICAL | `own-` | 12 |26| 2 | Error Handling | CRITICAL | `err-` | 12 |27| 3 | Memory Optimization | CRITICAL | `mem-` | 15 |28| 4 | API Design | HIGH | `api-` | 15 |29| 5 | Async/Await | HIGH | `async-` | 15 |30| 6 | Compiler Optimization | HIGH | `opt-` | 12 |31| 7 | Naming Conventions | MEDIUM | `name-` | 16 |32| 8 | Type Safety | MEDIUM | `type-` | 10 |33| 9 | Testing | MEDIUM | `test-` | 13 |34| 10 | Documentation | MEDIUM | `doc-` | 11 |35| 11 | Performance Patterns | MEDIUM | `perf-` | 11 |36| 12 | Project Structure | LOW | `proj-` | 11 |37| 13 | Clippy & Linting | LOW | `lint-` | 11 |38| 14 | Anti-patterns | REFERENCE | `anti-` | 15 |3940---4142## Quick Reference4344### 1. Ownership & Borrowing (CRITICAL)4546- [`own-borrow-over-clone`](rules/own-borrow-over-clone.md) - Prefer `&T` borrowing over `.clone()`47- [`own-slice-over-vec`](rules/own-slice-over-vec.md) - Accept `&[T]` not `&Vec<T>`, `&str` not `&String`48- [`own-cow-conditional`](rules/own-cow-conditional.md) - Use `Cow<'a, T>` for conditional ownership49- [`own-arc-shared`](rules/own-arc-shared.md) - Use `Arc<T>` for thread-safe shared ownership50- [`own-rc-single-thread`](rules/own-rc-single-thread.md) - Use `Rc<T>` for single-threaded sharing51- [`own-refcell-interior`](rules/own-refcell-interior.md) - Use `RefCell<T>` for interior mutability (single-thread)52- [`own-mutex-interior`](rules/own-mutex-interior.md) - Use `Mutex<T>` for interior mutability (multi-thread)53- [`own-rwlock-readers`](rules/own-rwlock-readers.md) - Use `RwLock<T>` when reads dominate writes54- [`own-copy-small`](rules/own-copy-small.md) - Derive `Copy` for small, trivial types55- [`own-clone-explicit`](rules/own-clone-explicit.md) - Make `Clone` explicit, avoid implicit copies56- [`own-move-large`](rules/own-move-large.md) - Move large data instead of cloning57- [`own-lifetime-elision`](rules/own-lifetime-elision.md) - Rely on lifetime elision when possible5859### 2. Error Handling (CRITICAL)6061- [`err-thiserror-lib`](rules/err-thiserror-lib.md) - Use `thiserror` for library error types62- [`err-anyhow-app`](rules/err-anyhow-app.md) - Use `anyhow` for application error handling63- [`err-result-over-panic`](rules/err-result-over-panic.md) - Return `Result`, don't panic on expected errors64- [`err-context-chain`](rules/err-context-chain.md) - Add context with `.context()` or `.with_context()`65- [`err-no-unwrap-prod`](rules/err-no-unwrap-prod.md) - Never use `.unwrap()` in production code66- [`err-expect-bugs-only`](rules/err-expect-bugs-only.md) - Use `.expect()` only for programming errors67- [`err-question-mark`](rules/err-question-mark.md) - Use `?` operator for clean propagation68- [`err-from-impl`](rules/err-from-impl.md) - Use `#[from]` for automatic error conversion69- [`err-source-chain`](rules/err-source-chain.md) - Use `#[source]` to chain underlying errors70- [`err-lowercase-msg`](rules/err-lowercase-msg.md) - Error messages: lowercase, no trailing punctuation71- [`err-doc-errors`](rules/err-doc-errors.md) - Document errors with `# Errors` section72- [`err-custom-type`](rules/err-custom-type.md) - Create custom error types, not `Box<dyn Error>`7374### 3. Memory Optimization (CRITICAL)7576- [`mem-with-capacity`](rules/mem-with-capacity.md) - Use `with_capacity()` when size is known77- [`mem-smallvec`](rules/mem-smallvec.md) - Use `SmallVec` for usually-small collections78- [`mem-arrayvec`](rules/mem-arrayvec.md) - Use `ArrayVec` for bounded-size collections79- [`mem-box-large-variant`](rules/mem-box-large-variant.md) - Box large enum variants to reduce type size80- [`mem-boxed-slice`](rules/mem-boxed-slice.md) - Use `Box<[T]>` instead of `Vec<T>` when fixed81- [`mem-thinvec`](rules/mem-thinvec.md) - Use `ThinVec` for often-empty vectors82- [`mem-clone-from`](rules/mem-clone-from.md) - Use `clone_from()` to reuse allocations83- [`mem-reuse-collections`](rules/mem-reuse-collections.md) - Reuse collections with `clear()` in loops84- [`mem-avoid-format`](rules/mem-avoid-format.md) - Avoid `format!()` when string literals work85- [`mem-write-over-format`](rules/mem-write-over-format.md) - Use `write!()` instead of `format!()` 86- [`mem-arena-allocator`](rules/mem-arena-allocator.md) - Use arena allocators for batch allocations87- [`mem-zero-copy`](rules/mem-zero-copy.md) - Use zero-copy patterns with slices and `Bytes`88- [`mem-compact-string`](rules/mem-compact-string.md) - Use `CompactString` for small string optimization89- [`mem-smaller-integers`](rules/mem-smaller-integers.md) - Use smallest integer type that fits90- [`mem-assert-type-size`](rules/mem-assert-type-size.md) - Assert hot type sizes to prevent regressions9192### 4. API Design (HIGH)9394- [`api-builder-pattern`](rules/api-builder-pattern.md) - Use Builder pattern for complex construction95- [`api-builder-must-use`](rules/api-builder-must-use.md) - Add `#[must_use]` to builder types96- [`api-newtype-safety`](rules/api-newtype-safety.md) - Use newtypes for type-safe distinctions97- [`api-typestate`](rules/api-typestate.md) - Use typestate for compile-time state machines98- [`api-sealed-trait`](rules/api-sealed-trait.md) - Seal traits to prevent external implementations99- [`api-extension-trait`](rules/api-extension-trait.md) - Use extension traits to add methods to foreign types100- [`api-parse-dont-validate`](rules/api-parse-dont-validate.md) - Parse into validated types at boundaries101- [`api-impl-into`](rules/api-impl-into.md) - Accept `impl Into<T>` for flexible string inputs102- [`api-impl-asref`](rules/api-impl-asref.md) - Accept `impl AsRef<T>` for borrowed inputs103- [`api-must-use`](rules/api-must-use.md) - Add `#[must_use]` to `Result` returning functions104- [`api-non-exhaustive`](rules/api-non-exhaustive.md) - Use `#[non_exhaustive]` for future-proof enums/structs105- [`api-from-not-into`](rules/api-from-not-into.md) - Implement `From`, not `Into` (auto-derived)106- [`api-default-impl`](rules/api-default-impl.md) - Implement `Default` for sensible defaults107- [`api-common-traits`](rules/api-common-traits.md) - Implement `Debug`, `Clone`, `PartialEq` eagerly108- [`api-serde-optional`](rules/api-serde-optional.md) - Gate `Serialize`/`Deserialize` behind feature flag109110### 5. Async/Await (HIGH)111112- [`async-tokio-runtime`](rules/async-tokio-runtime.md) - Use Tokio for production async runtime113- [`async-no-lock-await`](rules/async-no-lock-await.md) - Never hold `Mutex`/`RwLock` across `.await`114- [`async-spawn-blocking`](rules/async-spawn-blocking.md) - Use `spawn_blocking` for CPU-intensive work115- [`async-tokio-fs`](rules/async-tokio-fs.md) - Use `tokio::fs` not `std::fs` in async code116- [`async-cancellation-token`](rules/async-cancellation-token.md) - Use `CancellationToken` for graceful shutdown117- [`async-join-parallel`](rules/async-join-parallel.md) - Use `tokio::join!` for parallel operations118- [`async-try-join`](rules/async-try-join.md) - Use `tokio::try_join!` for fallible parallel ops119- [`async-select-racing`](rules/async-select-racing.md) - Use `tokio::select!` for racing/timeouts120- [`async-bounded-channel`](rules/async-bounded-channel.md) - Use bounded channels for backpressure121- [`async-mpsc-queue`](rules/async-mpsc-queue.md) - Use `mpsc` for work queues122- [`async-broadcast-pubsub`](rules/async-broadcast-pubsub.md) - Use `broadcast` for pub/sub patterns123- [`async-watch-latest`](rules/async-watch-latest.md) - Use `watch` for latest-value sharing124- [`async-oneshot-response`](rules/async-oneshot-response.md) - Use `oneshot` for request/response125- [`async-joinset-structured`](rules/async-joinset-structured.md) - Use `JoinSet` for dynamic task groups126- [`async-clone-before-await`](rules/async-clone-before-await.md) - Clone data before await, release locks127128### 6. Compiler Optimization (HIGH)129130- [`opt-inline-small`](rules/opt-inline-small.md) - Use `#[inline]` for small hot functions131- [`opt-inline-always-rare`](rules/opt-inline-always-rare.md) - Use `#[inline(always)]` sparingly132- [`opt-inline-never-cold`](rules/opt-inline-never-cold.md) - Use `#[inline(never)]` for cold paths133- [`opt-cold-unlikely`](rules/opt-cold-unlikely.md) - Use `#[cold]` for error/unlikely paths134- [`opt-likely-hint`](rules/opt-likely-hint.md) - Use `likely()`/`unlikely()` for branch hints135- [`opt-lto-release`](rules/opt-lto-release.md) - Enable LTO in release builds136- [`opt-codegen-units`](rules/opt-codegen-units.md) - Use `codegen-units = 1` for max optimization137- [`opt-pgo-profile`](rules/opt-pgo-profile.md) - Use PGO for production builds138- [`opt-target-cpu`](rules/opt-target-cpu.md) - Set `target-cpu=native` for local builds139- [`opt-bounds-check`](rules/opt-bounds-check.md) - Use iterators to avoid bounds checks140- [`opt-simd-portable`](rules/opt-simd-portable.md) - Use portable SIMD for data-parallel ops141- [`opt-cache-friendly`](rules/opt-cache-friendly.md) - Design cache-friendly data layouts (SoA)142143### 7. Naming Conventions (MEDIUM)144145- [`name-types-camel`](rules/name-types-camel.md) - Use `UpperCamelCase` for types, traits, enums146- [`name-variants-camel`](rules/name-variants-camel.md) - Use `UpperCamelCase` for enum variants147- [`name-funcs-snake`](rules/name-funcs-snake.md) - Use `snake_case` for functions, methods, modules148- [`name-consts-screaming`](rules/name-consts-screaming.md) - Use `SCREAMING_SNAKE_CASE` for constants/statics149- [`name-lifetime-short`](rules/name-lifetime-short.md) - Use short lowercase lifetimes: `'a`, `'de`, `'src`150- [`name-type-param-single`](rules/name-type-param-single.md) - Use single uppercase for type params: `T`, `E`, `K`, `V`151- [`name-as-free`](rules/name-as-free.md) - `as_` prefix: free reference conversion152- [`name-to-expensive`](rules/name-to-expensive.md) - `to_` prefix: expensive conversion153- [`name-into-ownership`](rules/name-into-ownership.md) - `into_` prefix: ownership transfer154- [`name-no-get-prefix`](rules/name-no-get-prefix.md) - No `get_` prefix for simple getters155- [`name-is-has-bool`](rules/name-is-has-bool.md) - Use `is_`, `has_`, `can_` for boolean methods156- [`name-iter-convention`](rules/name-iter-convention.md) - Use `iter`/`iter_mut`/`into_iter` for iterators157- [`name-iter-method`](rules/name-iter-method.md) - Name iterator methods consistently158- [`name-iter-type-match`](rules/name-iter-type-match.md) - Iterator type names match method159- [`name-acronym-word`](rules/name-acronym-word.md) - Treat acronyms as words: `Uuid` not `UUID`160- [`name-crate-no-rs`](rules/name-crate-no-rs.md) - Crate names: no `-rs` suffix161162### 8. Type Safety (MEDIUM)163164- [`type-newtype-ids`](rules/type-newtype-ids.md) - Wrap IDs in newtypes: `UserId(u64)`165- [`type-newtype-validated`](rules/type-newtype-validated.md) - Newtypes for validated data: `Email`, `Url`166- [`type-enum-states`](rules/type-enum-states.md) - Use enums for mutually exclusive states167- [`type-option-nullable`](rules/type-option-nullable.md) - Use `Option<T>` for nullable values168- [`type-result-fallible`](rules/type-result-fallible.md) - Use `Result<T, E>` for fallible operations169- [`type-phantom-marker`](rules/type-phantom-marker.md) - Use `PhantomData<T>` for type-level markers170- [`type-never-diverge`](rules/type-never-diverge.md) - Use `!` type for functions that never return171- [`type-generic-bounds`](rules/type-generic-bounds.md) - Add trait bounds only where needed172- [`type-no-stringly`](rules/type-no-stringly.md) - Avoid stringly-typed APIs, use enums/newtypes173- [`type-repr-transparent`](rules/type-repr-transparent.md) - Use `#[repr(transparent)]` for FFI newtypes174175### 9. Testing (MEDIUM)176177- [`test-cfg-test-module`](rules/test-cfg-test-module.md) - Use `#[cfg(test)] mod tests { }`178- [`test-use-super`](rules/test-use-super.md) - Use `use super::*;` in test modules179- [`test-integration-dir`](rules/test-integration-dir.md) - Put integration tests in `tests/` directory180- [`test-descriptive-names`](rules/test-descriptive-names.md) - Use descriptive test names181- [`test-arrange-act-assert`](rules/test-arrange-act-assert.md) - Structure tests as arrange/act/assert182- [`test-proptest-properties`](rules/test-proptest-properties.md) - Use `proptest` for property-based testing183- [`test-mockall-mocking`](rules/test-mockall-mocking.md) - Use `mockall` for trait mocking184- [`test-mock-traits`](rules/test-mock-traits.md) - Use traits for dependencies to enable mocking185- [`test-fixture-raii`](rules/test-fixture-raii.md) - Use RAII pattern (Drop) for test cleanup186- [`test-tokio-async`](rules/test-tokio-async.md) - Use `#[tokio::test]` for async tests187- [`test-should-panic`](rules/test-should-panic.md) - Use `#[should_panic]` for panic tests188- [`test-criterion-bench`](rules/test-criterion-bench.md) - Use `criterion` for benchmarking189- [`test-doctest-examples`](rules/test-doctest-examples.md) - Keep doc examples as executable tests190191### 10. Documentation (MEDIUM)192193- [`doc-all-public`](rules/doc-all-public.md) - Document all public items with `///`194- [`doc-module-inner`](rules/doc-module-inner.md) - Use `//!` for module-level documentation195- [`doc-examples-section`](rules/doc-examples-section.md) - Include `# Examples` with runnable code196- [`doc-errors-section`](rules/doc-errors-section.md) - Include `# Errors` for fallible functions197- [`doc-panics-section`](rules/doc-panics-section.md) - Include `# Panics` for panicking functions198- [`doc-safety-section`](rules/doc-safety-section.md) - Include `# Safety` for unsafe functions199- [`doc-question-mark`](rules/doc-question-mark.md) - Use `?` in examples, not `.unwrap()`200- [`doc-hidden-setup`](rules/doc-hidden-setup.md) - Use `# ` prefix to hide example setup code201- [`doc-intra-links`](rules/doc-intra-links.md) - Use intra-doc links: `[Vec]`202- [`doc-link-types`](rules/doc-link-types.md) - Link related types and functions in docs203- [`doc-cargo-metadata`](rules/doc-cargo-metadata.md) - Fill `Cargo.toml` metadata204205### 11. Performance Patterns (MEDIUM)206207- [`perf-iter-over-index`](rules/perf-iter-over-index.md) - Prefer iterators over manual indexing208- [`perf-iter-lazy`](rules/perf-iter-lazy.md) - Keep iterators lazy, collect() only when needed209- [`perf-collect-once`](rules/perf-collect-once.md) - Don't `collect()` intermediate iterators210- [`perf-entry-api`](rules/perf-entry-api.md) - Use `entry()` API for map insert-or-update211- [`perf-drain-reuse`](rules/perf-drain-reuse.md) - Use `drain()` to reuse allocations212- [`perf-extend-batch`](rules/perf-extend-batch.md) - Use `extend()` for batch insertions213- [`perf-chain-avoid`](rules/perf-chain-avoid.md) - Avoid `chain()` in hot loops214- [`perf-collect-into`](rules/perf-collect-into.md) - Use `collect_into()` for reusing containers215- [`perf-black-box-bench`](rules/perf-black-box-bench.md) - Use `black_box()` in benchmarks216- [`perf-release-profile`](rules/perf-release-profile.md) - Optimize release profile settings217- [`perf-profile-first`](rules/perf-profile-first.md) - Profile before optimizing218219### 12. Project Structure (LOW)220221- [`proj-lib-main-split`](rules/proj-lib-main-split.md) - Keep `main.rs` minimal, logic in `lib.rs`222- [`proj-mod-by-feature`](rules/proj-mod-by-feature.md) - Organize modules by feature, not type223- [`proj-flat-small`](rules/proj-flat-small.md) - Keep small projects flat224- [`proj-mod-rs-dir`](rules/proj-mod-rs-dir.md) - Use `mod.rs` for multi-file modules225- [`proj-pub-crate-internal`](rules/proj-pub-crate-internal.md) - Use `pub(crate)` for internal APIs226- [`proj-pub-super-parent`](rules/proj-pub-super-parent.md) - Use `pub(super)` for parent-only visibility227- [`proj-pub-use-reexport`](rules/proj-pub-use-reexport.md) - Use `pub use` for clean public API228- [`proj-prelude-module`](rules/proj-prelude-module.md) - Create `prelude` module for common imports229- [`proj-bin-dir`](rules/proj-bin-dir.md) - Put multiple binaries in `src/bin/`230- [`proj-workspace-large`](rules/proj-workspace-large.md) - Use workspaces for large projects231- [`proj-workspace-deps`](rules/proj-workspace-deps.md) - Use workspace dependency inheritance232233### 13. Clippy & Linting (LOW)234235- [`lint-deny-correctness`](rules/lint-deny-correctness.md) - `#![deny(clippy::correctness)]`236- [`lint-warn-suspicious`](rules/lint-warn-suspicious.md) - `#![warn(clippy::suspicious)]`237- [`lint-warn-style`](rules/lint-warn-style.md) - `#![warn(clippy::style)]`238- [`lint-warn-complexity`](rules/lint-warn-complexity.md) - `#![warn(clippy::complexity)]`239- [`lint-warn-perf`](rules/lint-warn-perf.md) - `#![warn(clippy::perf)]`240- [`lint-pedantic-selective`](rules/lint-pedantic-selective.md) - Enable `clippy::pedantic` selectively241- [`lint-missing-docs`](rules/lint-missing-docs.md) - `#![warn(missing_docs)]`242- [`lint-unsafe-doc`](rules/lint-unsafe-doc.md) - `#![warn(clippy::undocumented_unsafe_blocks)]`243- [`lint-cargo-metadata`](rules/lint-cargo-metadata.md) - `#![warn(clippy::cargo)]` for published crates244- [`lint-rustfmt-check`](rules/lint-rustfmt-check.md) - Run `cargo fmt --check` in CI245- [`lint-workspace-lints`](rules/lint-workspace-lints.md) - Configure lints at workspace level246247### 14. Anti-patterns (REFERENCE)248249- [`anti-unwrap-abuse`](rules/anti-unwrap-abuse.md) - Don't use `.unwrap()` in production code250- [`anti-expect-lazy`](rules/anti-expect-lazy.md) - Don't use `.expect()` for recoverable errors251- [`anti-clone-excessive`](rules/anti-clone-excessive.md) - Don't clone when borrowing works252- [`anti-lock-across-await`](rules/anti-lock-across-await.md) - Don't hold locks across `.await`253- [`anti-string-for-str`](rules/anti-string-for-str.md) - Don't accept `&String` when `&str` works254- [`anti-vec-for-slice`](rules/anti-vec-for-slice.md) - Don't accept `&Vec<T>` when `&[T]` works255- [`anti-index-over-iter`](rules/anti-index-over-iter.md) - Don't use indexing when iterators work256- [`anti-panic-expected`](rules/anti-panic-expected.md) - Don't panic on expected/recoverable errors257- [`anti-empty-catch`](rules/anti-empty-catch.md) - Don't use empty `if let Err(_) = ...` blocks258- [`anti-over-abstraction`](rules/anti-over-abstraction.md) - Don't over-abstract with excessive generics259- [`anti-premature-optimize`](rules/anti-premature-optimize.md) - Don't optimize before profiling260- [`anti-type-erasure`](rules/anti-type-erasure.md) - Don't use `Box<dyn Trait>` when `impl Trait` works261- [`anti-format-hot-path`](rules/anti-format-hot-path.md) - Don't use `format!()` in hot paths262- [`anti-collect-intermediate`](rules/anti-collect-intermediate.md) - Don't `collect()` intermediate iterators263- [`anti-stringly-typed`](rules/anti-stringly-typed.md) - Don't use strings for structured data264265---266267## Recommended Cargo.toml Settings268269```toml270[profile.release]271opt-level = 3272lto = "fat"273codegen-units = 1274panic = "abort"275strip = true276277[profile.bench]278inherits = "release"279debug = true280strip = false281282[profile.dev]283opt-level = 0284debug = true285286[profile.dev.package."*"]287opt-level = 3 # Optimize dependencies in dev288```289290---291292## How to Use293294This skill provides rule identifiers for quick reference. When generating or reviewing Rust code:2952961. **Check relevant category** based on task type2972. **Apply rules** with matching prefix2983. **Prioritize** CRITICAL > HIGH > MEDIUM > LOW2994. **Read rule files** in `rules/` for detailed examples300301### Rule Application by Task302303| Task | Primary Categories |304|------|-------------------|305| New function | `own-`, `err-`, `name-` |306| New struct/API | `api-`, `type-`, `doc-` |307| Async code | `async-`, `own-` |308| Error handling | `err-`, `api-` |309| Memory optimization | `mem-`, `own-`, `perf-` |310| Performance tuning | `opt-`, `mem-`, `perf-` |311| Code review | `anti-`, `lint-` |312313---314315## Sources316317This skill synthesizes best practices from:318- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)319- [Rust Performance Book](https://nnethercote.github.io/perf-book/)320- [Rust Design Patterns](https://rust-unofficial.github.io/patterns/)321- Production codebases: ripgrep, tokio, serde, polars, axum, deno322- Clippy lint documentation323- Community conventions (2024-2025)324325---326> Converted and distributed by [TomeVault](https://tomevault.io/claim/pythoninthegrasses) — claim your Tome and manage your conversions.327<!-- tomevault:4.0:skill_md:2026-04-13 -->