agentleFS
JSBtechnologiesJSBtechnologies/rustkb/skills/rust-idioms/SKILL.md

rust-idioms

Skill0 starsChanged 43 days agoMITView on GitHub

Current (Rust 1.96, edition 2024) idioms and decision rules for writing, reviewing, refactoring or debugging Rust code — any .rs file, Cargo.toml [lints]/rust-version, or Rust code review. Covers ownership and borrow-checker fixes without clone(), error handling (thiserror vs anyhow, unwrap/expect policy), traits and generics vs dyn, public API design (naming, conversions, builders, #[must_use], #[non_exhaustive], sealed traits), newtypes/typestate, iterators and closures, async/tokio (Send bounds, cancellation, blocking, locks across .await), threads/channels/Arc<Mutex>/atomics/ LazyLock, unsafe and FFI (SAFETY comments, unsafe extern), performance, testing (proptest, insta, nextest), macros, edition 2024 migration and MSRV, clippy/rustfmt configuration. Use it to avoid the mistakes AI agents make in Rust: outdated crates (lazy_static, structopt, failure), unwrap everywhere, needless clone, Arc<Mutex> by reflex, Box<dyn Error> in library APIs, blocking in async, over-generic code.

3 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions3 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 3

    1. irahardianto/awesome-agv★ 157same name
    2. jcanizalez/vibegrid★ 25same name
    3. tstapler/dotfiles★ 8same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository4 other files it gives its agents.

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 0 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 0

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If the rustkb MCP server is available, use it for facts this skill deliberately doesn't copy: search / get_item (versioned std and crate …

    line 23
  2. Very specific:

    ED-08: Use std over legacy crates: LazyLock/OnceLock (not lazy_static/once_cell), thread::scope, IsTerminal, cfg_select!

    line 31
  3. Very specific:

    TRAIT-01: Start concrete; introduce a trait only for a second real implementation (no FooService+FooServiceImpl).

    line 37
  4. Very specific:

    ASYNC-04: No blocking IO, thread::sleep or long CPU loops on async workers — spawn_blocking or rayon.

    line 41
  5. Very specific:

    ASYNC-05: Never hold a Mutex/RefCell guard across .await.

    line 42
  6. Very specific:

    UNSAFE-03: Every unsafe block has a // SAFETY: comment.

    line 44

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

rust-idioms

Opinionated, verified rules for idiomatic modern Rust. Each rule has a stable ID (ERR-01) you can cite in reviews. Read the core rules below, then open the one reference file that matches your task (routing table). Don't load every file.

If the rustkb MCP server is available, use it for facts this skill deliberately doesn't copy: search / get_item (versioned std and crate API docs), crate_info (current crate versions and features), check_advisories (RustSec), explain_lint (clippy/rustc lint docs), rust_release (what a Rust version stabilized). Never state a crate version or stabilization version from memory.

Core rules

  • ED-01 New crates: edition = "2024" and an explicit rust-version; never generate edition 2021.
  • ED-08 Use std over legacy crates: LazyLock/OnceLock (not lazy_static/once_cell), thread::scope, IsTerminal, cfg_select! (1.95+).
  • OWN-01 Parameters borrow the most general type: &str, &[T], &Path — never &String/&Vec<T>.
  • OWN-04 Fix borrow errors by restructuring (shorter borrows, field splitting, mem::take, entry API) before cloning.
  • ERR-01 Libraries return typed thiserror enums; never Box<dyn Error>, anyhow::Error or String in public APIs.
  • ERR-02 Applications use anyhow::Result and add .context() at every I/O/boundary call.
  • ERR-10 No .unwrap() in non-test code; .expect("invariant that makes this infallible") or ?.
  • TRAIT-01 Start concrete; introduce a trait only for a second real implementation (no FooService+FooServiceImpl).
  • TRAIT-02 Closed set of types → enum; open/runtime set → dyn Trait; hot generic paths → generics.
  • ITER-04 Collect fallible iterators into Result<Vec<_>, E>; no unwrap() inside map.
  • TYPE-02 Parse, don't validate: newtypes with private fields and one fallible constructor; states as enum variants, not structs of Options.
  • ASYNC-04 No blocking IO, thread::sleep or long CPU loops on async workers — spawn_blocking or rayon.
  • ASYNC-05 Never hold a Mutex/RefCell guard across .await; lock briefly with std::sync::Mutex.
  • CONC-02 Transfer ownership (channels, thread::scope) before reaching for Arc<Mutex<_>>.
  • UNSAFE-03 Every unsafe block has a // SAFETY: comment; every unsafe fn has a # Safety doc section.
  • PERF-01 Benchmark/profile before optimising; no unsafe or #[inline] sprinkling on a hunch.
  • LINT-04 Configure lints in [workspace.lints] (pedantic + cherry-picked restriction), not #![deny(warnings)].
  • LINT-07 Silence a lint only with #[expect(lint, reason = "..")] on the smallest item; never crate-wide #![allow].
  • LINT-11 Done means: cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, tests pass.

Routing table

SituationRead
Choosing parameter/return types; borrow-checker errors (E0499/E0502/E0505); Rc<RefCell>, Cow, lifetimes in structsreferences/ownership-borrowing.md (OWN)
Defining error types; ?, unwrap/expect, panics; main exit codes; thiserror vs anyhowreferences/error-handling.md (ERR)
Adding a trait or type parameter; generics vs impl Trait vs dyn vs enum; orphan rule; dyn compatibilityreferences/traits-generics.md (TRAIT)
Loops vs iterator chains; collect; returning iterators; closure Fn/FnMut/FnOnce; movereferences/iterators-closures.md (ITER)
Designing a public API: naming, From/TryFrom/AsRef, builders, #[must_use], #[non_exhaustive], sealed traits, docsreferences/api-design.md (API)
Newtypes, parse-don't-validate, typestate, enums instead of bools, NonZero, making invalid states unrepresentablereferences/types-and-state.md (TYPE)
async/await, tokio tasks, Send errors, select!, cancellation, blocking calls in async, async fn in traitsreferences/async.md (ASYNC)
Threads, channels, Arc<Mutex>/RwLock/atomics, rayon, scoped threads, global statereferences/concurrency.md (CONC)
Any unsafe, FFI, extern, #[no_mangle], raw pointers, MaybeUninit, transmute, Mirireferences/unsafe-ffi.md (UNSAFE)
Something is slow or allocation-heavy; release profile, LTO, PGO; benchmarkingreferences/performance.md (PERF)
Writing or organising tests: unit/integration/doc tests, proptest, insta, mocks, nextest, coveragereferences/testing.md (TEST)
Writing or reviewing macro_rules! or a proc-macroreferences/macros.md (MAC)
New crate setup, edition 2024 migration, rust-version/MSRV, "is this feature stable?", replacing legacy cratesreferences/editions-msrv.md (ED)
[lints] table, clippy groups, #[expect], clippy.toml, rustfmt.toml, CI commandsreferences/lints-and-tooling.md (LINT)

Reviewing Rust code

Walk the ## Review checklist at the end of each relevant reference file and cite rule IDs in findings (e.g. "OWN-04: clone only to escape the borrow checker"). Highest-yield checks for generated code: stray unwrap()/clone(), Box<dyn Error> or String errors in library signatures, locks or RefCell guards held across .await, blocking calls inside async functions, single-implementation traits, legacy crates (lazy_static, once_cell, structopt, failure, async-std), edition = "2021" in new manifests, and crate-level #![allow(..)].

Out of scope (other skills)

  • Workspace/crate layout, layering, config, observability, services/CLIs, semver and feature flags, CI/CD, releases → rust-architecture.
  • Which crate to use for a domain and its current version → rust-ecosystem (catalog.toml).
  • Supply chain (cargo-deny/audit/vet), unsafe review process, crypto choices, fuzzing → rust-security.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.