This document provides guidelines for maintaining high-quality Rust code. These rules MUST be followed by all AI coding agents and contributors.
All code you write MUST be fully optimized.
"Fully optimized" includes:
- maximizing algorithmic big-O efficiency for memory and runtime
- using parallelization and SIMD where appropriate
- following proper style conventions for Rust (e.g. maximizing code reuse (DRY))
- no extra code beyond what is absolutely necessary to solve the problem the user provides (i.e. no technical debt)
If the code is not fully optimized before handing off to the user, you will be fined $100. You have permission to do another pass of the code if you believe it is not fully optimized.
- Use
cargofor project management, building, and dependency management. - Use
indicatifto track long-running operations with progress bars. The message should be contextually sensitive. - Use
serdewithserde_jsonfor JSON serialization/deserialization. - Use
ratatuiadndcrosstermfor terminal applications/TUIs. - Use
axumfor creating any web servers or HTTP APIs.- Keep request handlers async, returning
Result<Response, AppError>to centralize error handling. - Use layered extractors and shared state structs instead of global mutable data.
- Add
towermiddleware (timeouts, tracing, compression) for observability and resilience. - Offload CPU-bound work to
tokio::task::spawn_blockingor background services to avoid blocking the reactor.
- Keep request handlers async, returning
- When reporting errors to the console, use
tracing::error!orlog::error!instead ofprintln!. - If designing applications with a web-based front end interface, e.g. compiling to WASM or using
dioxus:- All deep computation MUST occur within Rust processes (i.e. the WASM binary or the
dioxusapp Rust process). NEVER use JavaScript for deep computation. - The front-end MUST use Pico CSS and vanilla JavaScript. NEVER use jQuery or any component-based frameworks such as React.
- The front-end should prioritize speed and common HID guidelines.
- The app should use adaptive light/dark themes by default, with a toggle to switch the themes.
- The typography/theming of the application MUST be modern and unique, similar to that of popular single-page web/mobile. ALWAYS add an appropriate font for headers and body text. You may reference fonts from Google Fonts.
- NEVER use the Pico CSS defaults as-is: a separate CSS/SCSS file is encouraged. The design MUST logically complement the semantics of the application use case.
- ALWAYS rebuild the WASM binary if any underlying Rust code that affects it is touched.
- All deep computation MUST occur within Rust processes (i.e. the WASM binary or the
- For data processing:
- ALWAYS use
polarsinstead of other data frame libraries for tabular data manipulation. - If a
polarsdataframe will be printed, NEVER simultaneously print the number of entries in the dataframe nor the schema as it is redundant. - NEVER ingest more than 10 rows of a data frame at a time. Only analyze subsets of data to avoid overloading your memory context.
- ALWAYS use
- If using Python to implement Rust code using PyO3/
maturin:- Rebuild the Python package with
maturinafter finishing all Rust code changes. - ALWAYS use
uvfor Python package management and to create a.venvif it is not present. NEVER use the base system Python installation. - Ensure
.venvis added to.gitignore. - Ensure
ipykernelandipywidgetsis installed in.venvfor Jupyter Notebook compatability. This should not be in package requirements. - MUST keep functions focused on a single responsibility
- NEVER use mutable objects (lists, dicts) as default argument values
- Limit function parameters to 5 or fewer
- Return early to reduce nesting
- MUST use type hints for all function signatures (parameters and return values)
- NEVER use
Anytype unless absolutely necessary - MUST run mypy and resolve all type errors
- Use
Optional[T]orT | Nonefor nullable types
- Rebuild the Python package with
- MUST use meaningful, descriptive variable and function names
- MUST follow Rust API Guidelines and idiomatic Rust conventions
- MUST use 4 spaces for indentation (never tabs)
- NEVER use emoji, or unicode that emulates emoji (e.g. ✓, ✗). The only exception is when writing tests and testing the impact of multibyte characters.
- Use snake_case for functions/variables/modules, PascalCase for types/traits, SCREAMING_SNAKE_CASE for constants
- Limit line length to 100 characters (rustfmt default)
- Assume the user is a Python expert, but a Rust novice. Include additional code comments around Rust-specific nuances that a Python developer may not recognize.
- MUST include doc comments for all public functions, structs, enums, and methods
- MUST document function parameters, return values, and errors
- Keep comments up-to-date with code changes
- Include examples in doc comments for complex functions
Example doc comment:
/// Calculate the total cost of items including tax.
///
/// # Arguments
///
/// * `items` - Slice of item structs with price fields
/// * `tax_rate` - Tax rate as decimal (e.g., 0.08 for 8%)
///
/// # Returns
///
/// Total cost including tax
///
/// # Errors
///
/// Returns `CalculationError::EmptyItems` if items is empty
/// Returns `CalculationError::InvalidTaxRate` if tax_rate is negative
///
/// # Examples
///
/// ```
/// let items = vec![Item { price: 10.0 }, Item { price: 20.0 }];
/// let total = calculate_total(&items, 0.08)?;
/// assert_eq!(total, 32.40);
/// ```
pub fn calculate_total(items: &[Item], tax_rate: f64) -> Result<f64, CalculationError> {- MUST leverage Rust's type system to prevent bugs at compile time
- NEVER use
.unwrap()in library code; use.expect()only for invariant violations with a descriptive message - MUST use meaningful custom error types with
thiserror - Use newtypes to distinguish semantically different values of the same underlying type
- Prefer
Option<T>over sentinel values
- NEVER use
.unwrap()in production code paths - MUST use
Result<T, E>for fallible operations - MUST use
thiserrorfor defining error types andanyhowfor application-level errors - MUST propagate errors with
?operator where appropriate - Provide meaningful error messages with context using
.context()fromanyhow
- MUST keep functions focused on a single responsibility
- MUST prefer borrowing (
&T,&mut T) over ownership when possible - Limit function parameters to 5 or fewer; use a config struct for more
- Return early to reduce nesting
- Use iterators and combinators over explicit loops where clearer
- MUST keep types focused on a single responsibility
- MUST derive common traits:
Debug,Clone,PartialEqwhere appropriate - Use
#[derive(Default)]when a sensible default exists - Prefer composition over inheritance-like patterns
- Use builder pattern for complex struct construction
- Make fields private by default; provide accessor methods when needed
- MUST write unit tests for all new functions and types
- MUST mock external dependencies (APIs, databases, file systems)
- MUST use the built-in
#[test]attribute andcargo test - Follow the Arrange-Act-Assert pattern
- Do not commit commented-out tests
- Use
#[cfg(test)]modules for test code
- MUST avoid wildcard imports (
use module::*) except for preludes, test modules (use super::*), and prelude re-exports - MUST document dependencies in
Cargo.tomlwith version constraints - Use
cargofor dependency management - Organize imports: standard library, external crates, local modules
- Use
rustfmtto automate import formatting
- NEVER use
unsafeunless absolutely necessary; document safety invariants when used - MUST call
.clone()explicitly on non-Copytypes; avoid hidden clones in closures and iterators - MUST use pattern matching exhaustively; avoid catch-all
_patterns when possible - MUST use
format!macro for string formatting - Use iterators and iterator adapters over manual loops
- Use
enumerate()instead of manual counter variables - Prefer
if letandwhile letfor single-pattern matching
- MUST avoid unnecessary allocations; prefer
&stroverStringwhen possible - MUST use
Cow<'_, str>when ownership is conditionally needed - Use
Vec::with_capacity()when the size is known - Prefer stack allocation over heap when appropriate
- Use
ArcandRcjudiciously; prefer borrowing
- MUST use
SendandSyncbounds appropriately - MUST prefer
tokiofor async runtime in async applications - MUST use
rayonfor CPU-bound parallelism - Avoid
MutexwhenRwLockor lock-free alternatives are appropriate - Use channels (
mpsc,crossbeam) for message passing
- NEVER store secrets, API keys, or passwords in code. Only store them in
.env.- Ensure
.envis declared in.gitignore.
- Ensure
- MUST use environment variables for sensitive configuration via
dotenvyorstd::env - NEVER log sensitive information (passwords, tokens, PII)
- Use
secrecycrate for sensitive data types
- MUST write clear, descriptive commit messages
- NEVER commit commented-out code; delete it
- NEVER commit debug
println!statements ordbg!macros - NEVER commit credentials or sensitive data
- MUST use
rustfmtfor code formatting - MUST use
clippyfor linting and follow its suggestions - MUST ensure code compiles with no warnings (use
-D warningsflag in CI, not#![deny(warnings)]in source) - Use
cargofor building, testing, and dependency management - Use
cargo testfor running tests - Use
cargo docfor generating documentation - NEVER build with
cargo build --features python: this will always fail. Instead, ALWAYS usematurin.
- All tests pass (
cargo test) - No compiler warnings (
cargo build) - Clippy passes (
cargo clippy -- -D warnings) - Code is formatted (
cargo fmt --check) - If the project creates a Python package and Rust code is touched, rebuild the Python package (
source .venv/bin/activate && maturin develop --release --features python) - If the project creates a WASM package and Rust code is touched, rebuild the WASM package (
wasm-pack build --target web --out-dir web/pkg) - All public items have doc comments
- No commented-out code or debug statements
- No hardcoded credentials
Remember: Prioritize clarity and maintainability over cleverness.