skills/rust/SKILL.md
Rust development standards and patterns. Use when writing Rust outside of Bevy/Endless.
npx skillsauth add abix-/claude-blueprints rustInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
src/ with main.rs + modulessrc/lib.rs + src/main.rs, or workspace with crates/src/internal/ or pub(crate)Cargo.lock committed for binaries, not librariesanyhow::Result for app-level errorsthiserror? propagation over explicit match unless you need to transform.unwrap() in production paths — .expect("reason") if truly impossibleThe default in this codebase is zero heap allocations unless this specific call needs one. Applies anywhere the code runs at high frequency: per-frame callbacks, ProcessEvent trampolines, render loops, tight iterator inner-loops.
Hot-path budget is single-digit nanoseconds and zero allocator traffic per fire. To meet that:
String, Vec, Box, HashMap, formatted
strings, etc. on hot paths. Use &str, slices, stack
buffers ([u8; N]), or pre-allocated reusable storage.AtomicUsize mirroring queue
length lets the hot path bail with one relaxed load when
the queue is empty, without ever taking the mutex.AtomicUsize / OnceLock. Per-fire compare
is a pointer/integer compare, not a string compare.Cold paths (init, user clicks, error reporting) can allocate freely. The discipline is about hot paths only.
When you write a new hot-path code path, apply this from day one. Don't ship-then-optimize.
collect() with turbofish when type isn't inferred: .collect::<Vec<_>>()impl Trait in args for simple cases, generics when you need the type paramDebug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, DeserializeWhen you want a static REGISTRY: Registry = Registry::new(&[Def::new(...)]) and Def contains state with non-trivial Drop (mutex, atomic-with-cache, owned heap), Rust's const-eval rejects the temporary array literal with E0493: destructor of [Def; N] cannot be evaluated at compile-time.
Don't reach for the hoisted-array workaround (static DEFS: [Def; N] = [...]; static REGISTRY = Registry::new(&DEFS);) — that's clunky.
Do declare each Def as its own named static and store &[&'static Def] in the registry. References are Copy + Drop-free, so the slice literal const-evaluates fine:
static MATERIALS_DEF: StackDef = StackDef::new("materials", ...);
static CRAFTING_DEF: StackDef = StackDef::new("crafting", ...);
pub static STACKS: StackRegistry =
StackRegistry::new(&[&MATERIALS_DEF, &CRAFTING_DEF]);
Bonus: each Def is now a named symbol — better for debug, introspection, and direct ref access from other modules.
For Drop-free Defs (just &'static strs, primitives, fn pointers), &[Def] (slice of values) works without the indirection — pick based on whether the Def has Drop-having state.
cargo clippy before committing — fix warnings, don't suppresscargo fmt — no custom rustfmt.toml unless necessary--release for benchmarks and perf testing, debug for development#[cfg(test)] mod tests at bottom of filetests/ directoryassert_eq! over assert!(a == b) for better error messagesfn empty_input_returns_none()std::path::PathBuf not string concatenation for pathsstd::fs::canonicalize returns \\?\ prefix on Windows — handle or avoid.lines() which handles both \n and \r\nserde + serde_jsonclap with derivereqwest (async) or ureq (blocking)tokio (multi-thread) — only add if actually neededtracing over logRc/Arc as first resort — restructure ownership firstMutex is simplerunsafe — prove safe alternatives insufficient.clone() to silence borrow errors — scope borrows insteadtools
AutoHotkey v2 scripting standards for Windows automation, hotkeys, and game macros. Built from the official AHK v2 docs and the AHK community conventions. v1 reached EOL in March 2024.
data-ai
Analyze why Claude made its previous response -- trace reasoning to system prompt, CLAUDE.md, memory, skills, or context
tools
development
Build, test, and release Timberbot mod to GitHub and Steam Workshop