Skip to main content

chainsafe-rust-developer

Idiomatic Rust development at ChainSafe — implementation-level guidance for writing Rust in Forest, Mina-rs, ChainBridge Substrate, and other Rust projects. Use this skill whenever the user is writing Rust, asking how to do something in Rust, debugging Rust, picking between Rust patterns, dealing with errors via thiserror/anyhow, async/Tokio patterns, handling unwrap discipline, writing unsafe with SAFETY comments, testing with proptest or miri, or setting up Rust tooling. EVEN IF the user does not explicitly say "Rust" but the file is .rs. Triggers on "write a Rust function", "implement in Rust", "fix this Rust", "how do I X in Rust", "Tokio async", "Result and ?", "thiserror enum", "anyhow context", "unwrap or expect", "Arc<Mutex>", "spawn_blocking vs spawn", "miri test", "proptest", "cargo clippy", "rustfmt", "cargo.toml". Do NOT use for Rust architectural design (use chainsafe-rust-architect) or Rust PR review (use chainsafe-rust-reviewer).

跳到安装

来源信息

仓库
ChainSafe/engineering-handbook
最近来源活动
2026年7月20日 11:44
检测到的 SKILL.md 语言
英语
星标
7
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
chainsafe-rust-developer
description
Idiomatic Rust development at ChainSafe — implementation-level guidance for writing Rust in Forest, Mina-rs, ChainBridge Substrate, and other Rust projects. Use this skill whenever the user is writing Rust, asking how to do something in Rust, debugging Rust, picking between Rust patterns, dealing with errors via thiserror/anyhow, async/Tokio patterns, handling unwrap discipline, writing unsafe with SAFETY comments, testing with proptest or miri, or setting up Rust tooling. EVEN IF the user does not explicitly say "Rust" but the file is .rs. Triggers on "write a Rust function", "implement in Rust", "fix this Rust", "how do I X in Rust", "Tokio async", "Result and ?", "thiserror enum", "anyhow context", "unwrap or expect", "Arc<Mutex>", "spawn_blocking vs spawn", "miri test", "proptest", "cargo clippy", "rustfmt", "cargo.toml". Do NOT use for Rust architectural design (use chainsafe-rust-architect) or Rust PR review (use chainsafe-rust-reviewer).
metadata
{"type":"role-workflow","language":"rust","role":"developer","source":"languages/rust/developer.md","authored-via":"anthropic-skills:skill-creator (2026-05-27)"}
# Rust Developer Idiomatic Rust at ChainSafe. Full reference: [`languages/rust/developer.md`](../../languages/rust/developer.md). ## Tooling baselines CI gates that must pass: ```sh cargo fmt --all --check cargo clippy --all-targets -- -D warnings cargo build --workspace --all-targets cargo test --workspace cargo doc --no-deps cargo audit ``` For unsafe-heavy crates: also `cargo miri test`. ### Toolchain Pin with `rust-toolchain.toml`: ```toml [toolchain] channel = "1.79.0" components = ["rustfmt", "clippy"] ``` ### Dependencies - `Cargo.lock` committed for binaries; not for libraries published to crates.io. - `cargo audit` in CI. - `cargo deny` for license/source/version policy. - Workspace-level dependency declarations to keep versions consistent. - **Feature-gating.** Keep `default = []` lean — heavy deps (tracing subscribers, DB drivers, codecs, dev utilities) go behind optional features. Put mocks/test vectors behind `test-utils` or `mock` gates; never leak test deps into production builds. Features must be *additive* (Cargo unifies them across the workspace) — a gate may add behavior, never swap it. ## Error handling ```rust use anyhow::{Context, Result}; use thiserror::Error; #[derive(Error, Debug)] pub enum StoreError { #[error("key not found: {0}")] NotFound(String), #[error("backend failure")] Backend(#[from] BackendError), } pub fn fetch(key: &str) -> Result<Data> { let raw = read_backend(key).with_context(|| format!("reading {key}"))?; parse(&raw).context("parsing value") } ``` - **Library crates:** typed `thiserror` errors. - **Binary crates:** `anyhow::Result<T>`. - **`?` propagation.** Match only when transforming. ## `unwrap` and `expect` - **In tests:** fine. - **In production code:** require a `// SAFETY: ...` comment justifying the invariant. - **`expect("...")` over `unwrap()`** when you do use it — message helps debugging. ## Async - `#[tokio::main]` only in binaries. - `async fn` in trait is stable as of 1.75; older crates use `async-trait`. - `.await` propagates cancellation — hold no critical invariant across an `.await`. - `spawn` for async; `spawn_blocking` for CPU-bound. Mixing them up starves the runtime. - `Send + Sync + 'static` bounds on spawned tasks. - Every external `.await` (network, DB, cross-subsystem channel read) gets an explicit deadline via `tokio::time::timeout`. Bounded concurrency caps *how many*; this caps *how long* — an `.await` with no timeout hangs forever. ## Unsafe Every `unsafe` block: - `// SAFETY: ...` comment immediately above, explaining soundness. - Justification for choosing `unsafe` over safe alternatives. - `miri` test where possible. Forest's [`AI_POLICY.md`](https://github.com/ChainSafe/forest/blob/main/AI_POLICY.md) treats `unsafe` as security-relevant. Expect HARD-FAIL-tier review scrutiny on PRs introducing it. ## Testing - Unit tests in `#[cfg(test)] mod tests { ... }`. - Integration tests in `tests/`. - `#[tokio::test]` for async tests; `flavor = "multi_thread"` for parallel. - `proptest` for parsers, serializers, math, crypto. - `cargo nextest` for faster CI runs. - `miri` for unsafe code. ## Patterns - **Type-state when the protocol allows it.** Encode "must call A before B" in the type system. - **Newtypes for domain types.** `pub struct UserId(u64)`. - **`From` / `TryFrom`** for conversions over inherent `to_*` methods. - **`Deref` only for smart pointers** — don't fake inheritance. - **API & storage isolation.** Keep `#[derive(Serialize, Deserialize)]` and storage-schema concerns off domain types. Define serde/wire and DB DTOs at the boundary and map them explicitly to domain models. External edges only — not between internal modules. ## Anti-patterns - `unwrap()` in production paths without `// SAFETY: ...`. - `Box<dyn Error>` returns when you could be specific. - `async fn` that doesn't `.await` anything. - `Arc<Mutex<T>>` reached for reflexively when a channel would model the problem better. - `unsafe` without a soundness comment. - Public API leaking tokio types without a feature flag. ## Related - Full reference: [`languages/rust/developer.md`](../../languages/rust/developer.md) - Idioms: [`languages/rust/idioms.md`](../../languages/rust/idioms.md) - Gotchas: [`languages/rust/gotchas.md`](../../languages/rust/gotchas.md) - Sister roles: `chainsafe-rust-architect`, `chainsafe-rust-reviewer` - Forest AI policy: https://github.com/ChainSafe/forest/blob/main/AI_POLICY.md - Upstream: [Effective Rust](https://effective-rust.com/) · [The Rust Book](https://doc.rust-lang.org/book/)
在 GitHub 查看