Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Idiomatic Rust code guidance based on Apollo GraphQL's best practices handbook for ownership, errors, and performance.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: rust-best-practices3description: >4Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook. Use this skill when:5(1) writing new Rust code or functions,6(2) reviewing or refactoring existing Rust code,7(3) deciding between borrowing vs cloning or ownership patterns,8(4) implementing error handling with Result types,9(5) optimizing Rust code for performance,10(6) writing tests or documentation for Rust projects.11license: MIT12compatibility: Rust 1.70+, Cargo13metadata:14author: apollographql15version: "1.1.0"16allowed-tools: Bash(cargo:*) Bash(rustc:*) Bash(rustfmt:*) Bash(clippy:*) Read Write Edit Glob Grep17---1819# Rust Best Practices2021Apply these guidelines when writing or reviewing Rust code. Based on Apollo GraphQL's [Rust Best Practices Handbook](https://github.com/apollographql/rust-best-practices).2223## Best Practices Reference2425Before reviewing, familiarize yourself with Apollo's Rust best practices. Read ALL relevant chapters in the same turn in parallel. Reference these files when providing feedback:2627- [Chapter 1 - Coding Styles and Idioms](references/chapter_01.md): Borrowing vs cloning, Copy trait, Option/Result handling, iterators, comments28- [Chapter 2 - Clippy and Linting](references/chapter_02.md): Clippy configuration, important lints, workspace lint setup29- [Chapter 3 - Performance Mindset](references/chapter_03.md): Profiling, avoiding redundant clones, stack vs heap, zero-cost abstractions30- [Chapter 4 - Error Handling](references/chapter_04.md): Result vs panic, thiserror vs anyhow, error hierarchies31- [Chapter 5 - Automated Testing](references/chapter_05.md): Test naming, one assertion per test, snapshot testing32- [Chapter 6 - Generics and Dispatch](references/chapter_06.md): Static vs dynamic dispatch, trait objects33- [Chapter 7 - Type State Pattern](references/chapter_07.md): Compile-time state safety, when to use it34- [Chapter 8 - Comments vs Documentation](references/chapter_08.md): When to comment, doc comments, rustdoc35- [Chapter 9 - Understanding Pointers](references/chapter_09.md): Thread safety, Send/Sync, pointer types3637## Quick Reference3839### Borrowing & Ownership40- Prefer `&T` over `.clone()` unless ownership transfer is required41- Use `&str` over `String`, `&[T]` over `Vec<T>` in function parameters42- Small `Copy` types (≤24 bytes) can be passed by value43- Use `Cow<'_, T>` when ownership is ambiguous4445### Error Handling46- Return `Result<T, E>` for fallible operations; avoid `panic!` in production47- Never use `unwrap()`/`expect()` outside tests48- Use `thiserror` for library errors, `anyhow` for binaries only49- Prefer `?` operator over match chains for error propagation5051### Performance52- Always benchmark with `--release` flag53- Run `cargo clippy -- -D clippy::perf` for performance hints54- Avoid cloning in loops; use `.iter()` instead of `.into_iter()` for Copy types55- Prefer iterators over manual loops; avoid intermediate `.collect()` calls5657### Linting58Run regularly: `cargo clippy --all-targets --all-features --locked -- -D warnings`5960Key lints to watch:61- `redundant_clone` - unnecessary cloning62- `large_enum_variant` - oversized variants (consider boxing)63- `needless_collect` - premature collection6465Use `#[expect(clippy::lint)]` over `#[allow(...)]` with justification comment.6667### Testing68- Name tests descriptively: `process_should_return_error_when_input_empty()`69- One assertion per test when possible70- Use doc tests (`///`) for public API examples71- Consider `cargo insta` for snapshot testing generated output7273### Generics & Dispatch74- Prefer generics (static dispatch) for performance-critical code75- Use `dyn Trait` only when heterogeneous collections are needed76- Box at API boundaries, not internally7778### Type State Pattern79Encode valid states in the type system to catch invalid operations at compile time:80```rust81struct Connection<State> { /* ... */ _state: PhantomData<State> }82struct Disconnected;83struct Connected;8485impl Connection<Connected> {86fn send(&self, data: &[u8]) { /* only connected can send */ }87}88```8990### Documentation91- `//` comments explain *why* (safety, workarounds, design rationale)92- `///` doc comments explain *what* and *how* for public APIs93- Every `TODO` needs a linked issue: `// TODO(#42): ...`94- Enable `#![deny(missing_docs)]` for libraries95