# Toolchains Rust Core

> Core Rust toolchain conventions — ownership/borrowing patterns, error handling, async with tokio, and idiomatic project structure for the rust-engineer agent

- Skill: `bobmatnyc/toolchains-rust-core-2` (Agent Skill)
- Install (CLI): `npx skillmds@latest add bobmatnyc/toolchains-rust-core-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bobmatnyc/toolchains-rust-core-2/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: bobmatnyc (https://skillmd.com/u/bobmatnyc)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/bobmatnyc/toolchains-rust-core-2

---


# Rust Core Toolchain Conventions

## Edition and Toolchain

- Target **Rust 2024 edition**. MSRV is set by the most-constrained transitive dependency,
  not the edition floor — pin it explicitly in `Cargo.toml` (`rust-version = "..."`).
- Gate every change on `cargo fmt --check`, `cargo clippy -- -D warnings`, and `cargo test`.
- Prefer `cargo nextest run` for faster, isolated test execution when available.

## Ownership and Borrowing

- **Borrow by default, own only when necessary.** Accept `&str` / `&[T]` in function
  signatures, not `String` / `Vec<T>`, unless the function must take ownership.
- Return owned values; let callers borrow. Avoid returning references tied to locals.
- Reach for `Cow<'_, str>` when a value is usually borrowed but occasionally owned.
- Use `Rc`/`Arc` only for genuine shared ownership; prefer passing references first.
- Interior mutability: `Cell`/`RefCell` for single-threaded, `Mutex`/`RwLock` (under `Arc`)
  for shared-state concurrency. Never hold a lock across an `.await`.

## Error Handling

- **Never `unwrap()`/`expect()`/`panic!` in library code.** Return `Result<T, E>`.
- Libraries: define a typed error enum with `thiserror`. Applications: `anyhow::Result`
  with `.context(...)` to add provenance at each boundary.
- Use the `?` operator for propagation; convert errors with `From`/`#[from]`.
- Reserve `panic!` for truly unreachable invariants, and document why.

## Async with tokio

- Use `#[tokio::main]` (or an explicit runtime) and `async`/`.await` for I/O-bound work.
- Spawn concurrent work with `tokio::spawn`; join with `tokio::join!` or `try_join!`.
- Apply explicit timeouts via `tokio::time::timeout` on all external calls.
- Offload CPU-bound work with `tokio::task::spawn_blocking` — never block the runtime.
- Hold no `std::sync` lock across an `.await`; use `tokio::sync` primitives instead.

## Project Structure and Idioms

- One responsibility per module; expose a curated public API via `pub` in `lib.rs`.
- Derive `Debug`, and `Clone`/`PartialEq`/`Eq` where cheap and meaningful.
- Model state with enums + exhaustive `match`; avoid boolean-flag soup.
- Prefer iterator chains over manual index loops; they are clearer and often faster.
- Use newtypes (`struct UserId(u64)`) to make illegal states unrepresentable.
- Write doctests for public functions; they double as runnable documentation.

