Skip to content

Rust Code Quality Standards

Type: Reference (Information-Oriented)

Code quality standards, lint rules, and idioms enforced across all amplihack-rs Rust crates. These standards are checked automatically in CI and must pass before any PR is merged.


Quality Gates

Every PR must satisfy all four gates before merging:

Gate Command Expectation
Lint cargo clippy -- -D warnings Zero warnings, zero errors
Format cargo fmt --all --check No format drift
Tests cargo test --workspace All tests pass, no regressions
Dead code Enforced via clippy No unused items without annotation

Run locally in sequence:

cargo fmt --all
cargo clippy -- -D warnings
cargo test --workspace

Clippy Lint Rules

Zero-warnings policy

The entire workspace compiles with -D warnings, which promotes every clippy warning to a hard error. No warnings are permitted without an explicit, documented #[allow(...)] attribute.

Inlined format arguments (uninlined_format_args)

Use inlined variable syntax in all format strings:

// ✅ correct
let msg = format!("{name} failed with {code}");
tracing::warn!("{path} not found");

// ❌ wrong — triggers uninlined_format_args
let msg = format!("{} failed with {}", name, code);
tracing::warn!("{} not found", path);

This applies to format!, println!, eprintln!, write!, writeln!, tracing::info!, tracing::warn!, tracing::error!, and all similar macros.

To batch-fix the entire workspace at once:

cargo clippy --fix --allow-dirty --allow-staged -- -D warnings
cargo fmt --all

Design Patterns

Associated functions vs methods

Prefer associated functions (no self) for pure transformations that do not need instance state. Use &self only when the function actually reads from self.

// ✅ correct — pure transformation, no instance state needed
impl SettingsGenerator {
    pub fn merge_settings(base: &Value, overrides: &Value) -> Value {
        // ...
    }
}

// Call site
let merged = SettingsGenerator::merge_settings(&base, &overrides);

// ❌ wrong — unnecessarily borrows self
impl SettingsGenerator {
    pub fn merge_settings(&self, base: &Value, overrides: &Value) -> Value {
        // never reads self fields
    }
}

The only_used_in_recursion clippy lint will flag methods where self is passed through recursion but never actually read. Convert these to associated functions.


Error Handling

See CONTRIBUTING_RUST.md for the error strategy table. In summary:

Crate type Error crate Pattern
Library (amplihack-* without binary) thiserror Typed enum Error
Binary / CLI anyhow .context("what we were doing")

Never use Box<dyn Error> or unwrap() in library crates.


Format Style

rustfmt.toml sets the workspace format configuration. Key settings:

Option Value Effect
edition 2024 Rust 2024 edition formatting
max_width 100 Line length cap

Run cargo fmt --all to apply; cargo fmt --all --check to verify.


CI Integration

The quality gates run in .github/workflows/ on every push and PR:

lint job      → cargo clippy -- -D warnings
fmt job       → cargo fmt --all --check
test job      → cargo test --workspace

All three must pass for the merge button to be enabled. There are no optional quality gates — all are required.


Common Fixes Reference

Warning Root cause Fix
uninlined_format_args format!("{}", x) Change to format!("{x}")
only_used_in_recursion &self method that never reads self Convert to associated function
dead_code on constant Constant with no call site Remove the constant (do not annotate with #[allow(dead_code)] to silence)
needless_pass_by_ref_mut &mut T param that isn't mutated Change to &T
clippy::redundant_closure \|x\| f(x) Replace with f
clippy::match_wildcard_for_single_variants _ => in exhaustive enum match Add explicit arms