← ClaudeAtlas

coding-rustlisted

Use when writing or reviewing Rust and deciding how to handle errors, secrets or credentials, dependency/crate choices, or type design - or when a review flags a synthetic std::io::Error used for a non-IO condition, a non-constant-time secret/token comparison, an inline --password, a heavyweight crate pulled in for one narrow job, or a struct whose invalid field combinations are constructible.
bitranox/bitranox-skills · ★ 1 · AI & Automation · score 57
Install: claude install-skill bitranox/bitranox-skills
# coding-rust Idioms and review checks for Rust, distilled from real review findings. Apply when writing or reviewing Rust; each rule states the failure it prevents. ## Errors - **Never use `std::io::Error::new(...)` / `std::io::Error::other(...)` for a non-IO condition.** A synthetic IO error erases the type, so callers cannot pattern-match on what went wrong. Add a dedicated variant to the crate's own error enum instead, with `thiserror`: ```rust #[derive(thiserror::Error, Debug)] pub enum Error { #[error("frobnicator {0} is out of range")] OutOfRange(u32), #[error(transparent)] Io(#[from] std::io::Error), // real IO stays IO } ``` - **Preserve the error chain.** Wrap with context (`anyhow::Context::context`, or a `#[from]`/`#[source]` on a typed variant) rather than discarding the cause behind a fresh generic message. The source chain is what makes a failure debuggable. ## Secrets and credentials - **Constant-time comparison for secrets** (passwords, tokens, HMAC/auth responses). A short-circuiting `iter.zip(other).all(|(a, b)| a == b)` leaks length/prefix timing. Use an XOR-fold (or a vetted constant-time crate such as `subtle`): ```rust let equal = expected.iter().zip(response) .fold(0u8, |acc, (a, b)| acc | (a ^ b)) == 0 && expected.len() == response.len(); ``` - **`--password-file PATH` is the primary CLI interface for a secret, `--password VALUE` only a convenience fallback.** An inline value is