| name | rust |
| description | Language-specific super-code guidelines for rust. |
| risk | safe |
| source | community |
| date_added | 2026-06-16 |
Rust: Idiomatic Efficiency Reference
Table of Contents
- Ownership & Borrowing
- Error Handling
- Iterators
- Pattern Matching
- Structs & Enums
- Concurrency
- Anti-patterns specific to Rust
1. Ownership & Borrowing {#ownership}
fn get_name(user: &User) -> String {
user.name.clone()
}
fn get_name(user: &User) -> &str {
&user.name
}
fn print_name(name: String) {
println!("{name}");
}
fn print_name(name: &str) {
println!("{name}");
}
let key = id.to_string();
map.get(&key)
map.get(id)
Prefer &str over String in function parameters unless the function needs to own the data.
2. Error Handling {#errors}
let file = File::open(path).unwrap();
let file = File::open(path)
.map_err(|e| AppError::Io { path: path.to_owned(), source: e })?;
match do_thing() {
Ok(v) => v,
Err(e) => return Err(e),
}
let v = do_thing()?;
fn run() -> Result<(), Box<dyn std::error::Error>> { ... }
use anyhow::{Context, Result};
fn run() -> Result<()> {
do_thing().context("failed during run")?;
Ok(())
}
enum Error { FileOpen, FileRead, Parse, Network, ... }
#[derive(thiserror::Error, Debug)]
enum Error {
#[error("io error")] Io(#[from] std::io::Error),
#[error("parse error")] Parse(#[from] serde_json::Error),
}
3. Iterators {#iterators}
let mut result = Vec::new();
for item in &items {
if item.active {
result.push(item.name.to_uppercase());
}
}
let result: Vec<_> = items.iter()
.filter(|i| i.active)
.map(|i| i.name.to_uppercase())
.collect();
let mut total = 0;
for order in &orders { total += order.amount; }
let total: u64 = orders.iter().map(|o| o.amount).sum();
for i in 0..items.len() {
process(&items[i]);
}
for item in &items {
process(item);
}
for (i, item) in items.iter().enumerate() {
process(i, item);
}
Chain iterators lazily; only .collect() when you actually need a concrete collection.
4. Pattern Matching {#patterns}
if let Some(x) = opt {
if x > 0 {
use(x)
}
}
if let Some(x) = opt.filter(|&x| x > 0) {
use(x)
}
match opt {
Some(x) if x > 0 => use(x),
_ => {}
}
match status {
Status::Active => true,
Status::Pending => true,
Status::Inactive => false,
}
matches!(status, Status::Active | Status::Pending)
fn area(shape: &Shape) -> f64 {
match shape {
Shape::Circle(c) => { let r = c.radius; r * r * PI }
Shape::Rect(r) => { let w = r.width; let h = r.height; w * h }
}
}
match shape {
Shape::Circle(Circle { radius, .. }) => radius * radius * PI,
Shape::Rect(Rect { width, height }) => width * height,
}
5. Structs & Enums {#structs}
enum State { Running(bool) }
enum State { Running, Paused, Stopped }
struct Config {
timeout: Option<u64>,
retries: Option<u32>,
base_url: Option<String>,
}
#[derive(Default)]
struct Config {
timeout: u64,
retries: u32,
base_url: String,
}
pub struct Percentage { pub value: f64 }
pub struct Percentage(f64);
impl Percentage {
pub fn new(v: f64) -> Option<Self> {
(0.0..=100.0).contains(&v).then_some(Self(v))
}
}
6. Concurrency {#concurrency}
let data = Arc::new(Mutex::new(vec![...]));
let data = Arc::new(RwLock::new(vec![...]));
for item in items {
std::thread::spawn(|| process(item));
}
use rayon::prelude::*;
items.par_iter().for_each(|item| process(item));
For async: prefer tokio::spawn + JoinHandle over manual channels for structured concurrency. Use tokio::join! for concurrent awaits.
7. Anti-patterns specific to Rust {#antipatterns}
| Anti-pattern | Preferred |
|---|
.clone() to appease borrow checker | reconsider lifetime or restructure |
.unwrap() in non-test code | ? operator or explicit handling |
impl Trait in return position hiding complex type | name the type or use Box<dyn Trait> intentionally |
String parameter when &str suffices | &str for params, String for owned storage |
Nested Option<Option<T>> | rethink the data model |
unsafe block without a safety comment | always document the invariant being upheld |
Vec<Box<T>> when Vec<T> works | avoid heap allocation inside collections unless T is unsized |
Manual Drop for cleanup that ? handles | let RAII + ? do it |
Limitations
- These are language-specific guidelines and do not cover overall architectural decisions.
- Over-compression might reduce readability; apply judgement.