| name | swe-programming-rust |
| description | Rust coding standards from authoritative docs/explanation/software-engineering/programming-languages/rust/ documentation |
Rust Coding Standards
Purpose
Progressive disclosure of Rust coding standards for agents writing Rust code.
Usage: Auto-loaded for agents when writing Rust code. Provides quick reference to idioms, best practices, and antipatterns.
Authoritative Source: docs/explanation/software-engineering/programming-languages/rust/README.md
Prerequisite Knowledge
IMPORTANT: This skill provides OSE Platform-specific style guides, not educational tutorials.
Complete the AyoKoding Rust learning path first:
- Rust Learning Path - 0-95% language coverage
- Rust By Example - 75+ annotated examples
See: Programming Language Documentation Separation
Quick Standards Reference
Naming Conventions
Types/Traits/Enums: PascalCase - ZakatCalculator, MurabahaContract, PaymentStatus
Functions/Variables/Modules: snake_case - calculate_zakat, total_amount, zakat_service
Constants/Statics: UPPER_SNAKE_CASE - MAX_NISAB_THRESHOLD, ZAKAT_RATE
Lifetimes: short lowercase - 'a, 'b (descriptive when helpful: 'contract)
Error Handling (Result/Option)
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ZakatError {
#[error("Wealth cannot be negative: {0}")]
NegativeWealth(rust_decimal::Decimal),
#[error("Repository error: {0}")]
Repository(#[from] sqlx::Error),
}
pub fn calculate_zakat(
wealth: Decimal,
nisab: Decimal,
) -> Result<Decimal, ZakatError> {
if wealth < Decimal::ZERO {
return Err(ZakatError::NegativeWealth(wealth));
}
Ok(if wealth >= nisab { wealth * dec!(0.025) } else { Decimal::ZERO })
}
pub async fn process_payment(wealth: Decimal) -> Result<Payment, ZakatError> {
let nisab = repository.get_nisab().await?;
let amount = calculate_zakat(wealth, nisab)?;
Ok(Payment::new(amount))
}
let amount = calculate_zakat(wealth, nisab).unwrap();
Ownership and Borrowing
fn format_contract(contract: &MurabahaContract) -> String {
format!("Contract {}: {}", contract.id, contract.amount)
}
fn create_contract(id: String, amount: Decimal) -> MurabahaContract {
MurabahaContract { id, amount }
}
fn bad_format(contract: MurabahaContract) -> String {
format!("Contract {}", contract.id)
}
Idiomatic Iterators
let total_zakat: Decimal = contracts
.iter()
.filter(|c| c.wealth >= nisab_threshold)
.map(|c| c.wealth * dec!(0.025))
.sum();
let mut total = Decimal::ZERO;
for contract in &contracts {
if contract.wealth >= nisab_threshold {
total += contract.wealth * dec!(0.025);
}
}
Newtype Pattern for Domain Types
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ContractId(String);
impl ContractId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
fn get_contract(id: String) -> Option<MurabahaContract> { ... }
Async with Tokio/Axum
use axum::{extract::{Path, State}, Json, http::StatusCode};
async fn calculate_zakat_handler(
State(repo): State<Arc<dyn ZakatRepository>>,
Json(request): Json<ZakatRequest>,
) -> Result<Json<ZakatResponse>, (StatusCode, String)> {
let nisab = repo.get_nisab().await
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
let amount = calculate_zakat(request.wealth, nisab)
.map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
Ok(Json(ZakatResponse { amount }))
}
Unsafe Code Policy (MANDATORY)
MUST forbid unsafe code in both lib.rs and main.rs — the attribute is not inherited between targets:
#![forbid(unsafe_code)]
#![forbid(unsafe_code)]
MUST also encode at manifest level in Cargo.toml:
[lints.rust]
unsafe_code = "forbid"
Infrastructure crates requiring unsafe MUST include a // SAFETY: comment on every unsafe block.
See: Code Quality Standards §Unsafe Code Policy
Cargo.toml Required Structure
MUST declare edition, rust-version, and [lints.rust]. MUST configure release profile with LTO and panic = "abort":
[package]
name = "my-crate"
version = "0.1.0"
edition = "2024"
rust-version = "1.88"
[lints.rust]
unsafe_code = "forbid"
[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1
panic = "abort"
strip = "symbols"
rust-version (MSRV) ≠ channel in rust-toolchain.toml (installed toolchain). Installed ≥ MSRV is the invariant.
See: Build Configuration
Clippy and rustfmt (MANDATORY)
edition = "2024"
max_width = 100
use_small_heuristics = "Default"
reorder_imports = true
reorder_modules = true
Configure Clippy via [lints.clippy] in Cargo.toml (not CLI flags) — checked into source
control, applies consistently across contributors and CI:
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
must_use_candidate = "allow"
missing_errors_doc = "allow"
unwrap_used = "deny"
panic = "deny"
undocumented_unsafe_blocks = "deny"
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test
Comprehensive Documentation
Authoritative Index: docs/explanation/software-engineering/programming-languages/rust/README.md
Mandatory Standards
- Coding Standards
- Testing Standards
- Code Quality Standards
- Build Configuration
Context-Specific Standards
- Error Handling
- Concurrency
- Memory Management
- Type Safety
- Performance
- Security
- API Standards
- DDD Standards
Related Skills
- docs-applying-content-quality
- repo-practicing-trunk-based-development
References