Rust style rules
Standing rules for Rust an assistant writes, covering ownership-first APIs, Result over panic, clippy-clean code, typed errors, async hygiene and minimal, justified unsafe.
When you write or change Rust code in this project:
Tooling
- Code must pass
cargo fmtandcargo clippy --all-targetswith no warnings under the project's lint settings. - Never silence a lint crate-wide. Allow a specific lint on the narrowest item, with a comment explaining why.
- Use the edition and minimum Rust version in
Cargo.toml. Add a dependency only when it earns its place, with the fewest features needed.
Ownership and APIs
- Borrow in parameters when the function does not keep the value:
&str,&[T],&Pathorimpl AsRef<Path>. Take ownership (String,Vec<T>) when the value is stored. - Do not add
.clone()just to satisfy the borrow checker. Restructure the code first, and when a clone is the right answer, make it visible and cheap or explain it. - Return owned values or iterators rather than references tied to temporary state. Use
Cowwhen a value is only sometimes owned. - Model states with enums rather than booleans or sentinel values, and wrap ids and units in newtypes.
- Implement standard traits (
From,TryFrom,Display,Default,Debug) instead of ad hoc conversion methods, and mark results that must not be ignored with#[must_use].
Errors
- Return
Resultfor anything that can fail at runtime, and propagate with?. - Do not call
unwrap()in library or request-handling code. Useexpect("reason this cannot fail")only for real invariants. - Follow the project's error approach. Where there is none, use typed error enums (for example with
thiserror) in libraries and contextual errors (for exampleanyhowwith.context(...)) in binaries. - Never panic across an FFI boundary or in a
Dropimplementation.
Unsafe
- Avoid
unsafe. If it is necessary, keep the block as small as possible, put a// SAFETY:comment on it that states the invariants that make it sound, and wrap it in a safe API. - Document every
unsafe fnwith a# Safetysection, and test unsafe code under Miri where the project supports it.
Concurrency and async
- Prefer message passing or owned data over shared mutable state. When state is shared, use
Arcwith aMutexorRwLockand keep critical sections short. - Never hold a
std::sync::Mutexguard across.await. Use the runtime's async mutex or restructure. - Never block inside async code. Move blocking or CPU-heavy work to
spawn_blockingor a dedicated thread.
Style
- Prefer iterator chains to index loops when they read clearly, and avoid collecting into a
Veconly to iterate it again. - Keep items private by default, and use
pub(crate)beforepub. - Document public items with
///comments, with an example for non-trivial APIs. - Put unit tests in a
#[cfg(test)] mod testsbeside the code, and integration tests intests/.
details
- kind
- Rule: standing instructions for everything the assistant does
- domain
- Software engineering
- category
- Conventions
- made for
- Software engineer, Backend engineer, Embedded engineer
- risk
- read-only
- version
- v1.0.0 · experimental
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai
use in
npx @hermes-hq/hodios install rust-style-rules --target claude-codenpx skills add hermes-hq/hodios-dist --skill rust-style-rules -a claude-codeRules are always-on instructions, so they are not in the plugins: add the skill, or paste the text into CLAUDE.md.
pairs well with
All of ConventionsTest-writing rules
Standing rules for tests an assistant writes, covering behaviour over implementation, no sleeps, deterministic data, mocks only at boundaries and one reason to fail per test.
test-writing-rulesHTTP API design rules
Rules for HTTP APIs covering resource naming, status codes, problem+json errors, cursor pagination, idempotency keys and versioning. Load when designing or changing HTTP endpoints.
api-design-rulesC# style rules
Standing rules for C# an assistant writes, covering nullable reference types, async all the way with cancellation tokens, records and pattern matching, dependency injection and xUnit tests.
csharp-style-rulesGo style rules
Standing rules for Go an assistant writes, covering wrapped errors, context propagation, small consumer-side interfaces, table-driven tests and no goroutines without an owner.
go-style-rulesJava style rules
Standing rules for Java an assistant writes, covering modern language features, immutability, Optional and null handling, exceptions, restrained streams, records and JUnit 5 tests.
java-style-rulesPython style rules
Standing rules for Python an assistant writes, covering type hints, pathlib, logging over print, explicit exceptions, safe subprocess calls, project layout and the project's own tooling.
python-style-rules