rust-skills

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.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rust-skills" with this command: npx skills add jamals86/kalamdb/jamals86-kalamdb-rust-skills

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

  1. 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>

  1. 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

  1. 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

  1. 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

  1. 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)

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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:

  • Rust API Guidelines

  • Rust Performance Book

  • Rust Design Patterns

  • Production codebases: ripgrep, tokio, serde, polars, axum, deno

  • Clippy lint documentation

  • Community conventions (2024-2025)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

vercel-composition-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

datafusion

No summary provided by upstream source.

Repository SourceNeeds Review
General

raft

No summary provided by upstream source.

Repository SourceNeeds Review