| name | rust-development |
| description | Rust language expertise for writing safe, performant, production-quality Rust code. Primary language for the Loom project. Use for Rust development, ownership patterns, error handling, async/await, cargo management, CLI tools, and serialization. |
Cargo and Project Structure
[package]
name = "myproject"
version = "0.1.0"
edition = "2021"
rust-version = "1.75"
[dependencies]
tokio = { version = "1.35", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
anyhow = "1.0"
[dev-dependencies]
criterion = "0.5"
mockall = "0.12"
[features]
default = []
full = ["feature-a", "feature-b"]
feature-a = []
feature-b = ["dep:optional-dep"]
[[bench]]
name = "my_benchmark"
harness = false
Workspace Structure
myworkspace/
├── Cargo.toml # Workspace root
├── crates/
│ ├── core/
│ │ ├── Cargo.toml
│ │ └── src/
│ ├── api/
│ │ ├── Cargo.toml
│ │ └── src/
│ └── cli/
│ ├── Cargo.toml
│ └── src/
Key Concepts
Ownership, Borrowing, and Lifetimes
fn take_ownership(s: String) {
println!("{}", s);
}
fn main() {
let s = String::from("hello");
take_ownership(s);
}
fn borrow(s: &String) {
println!("{}", s);
}
fn borrow_mut(s: &mut String) {
s.push_str(" world");
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
struct <> {
input: & ,
position: ,
}
<> Parser<> {
(input: & ) {
Parser { input, position: }
}
(&) <> {
.input[.position..].().()
}
}
{
(&, key: &) <&> {
.map.(key).(|s| s.())
}
}
Error Handling
use std::error::Error;
use std::fmt;
use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum AppError {
#[error("IO error: {0}")]
Io(#[from] io::Error),
#[error("Parse error at line {line}: {message}")]
Parse { line: usize, message: String },
#[error("Not found: {0}")]
NotFound(String),
#[error("Validation failed: {0}")]
Validation(String),
}
use anyhow::{Context, Result, bail, ensure};
fn read_config(path: &str) -> Result<Config> {
let content = std::fs::read_to_string(path)
.with_context(|| format!("Failed to read config from {}", path))?;
let config: Config = serde_json::from_str(&content)
.context("Failed to parse config JSON")?;
ensure!(!config.name.is_empty(), "Config name cannot be empty");
config.port == {
bail!();
}
(config)
}
(path: &) <<Record>, AppError> {
= std::fs::(path)?;
= (&content)?;
(records)
}
(users: &[User], name: &) <&User> {
users.().(|u| u.name == name)
}
(users: &[User], name: &) <> {
users
.()
.(|u| u.name == name)
.(|u| u.email.())
}
(users: &[User], name: &) <&User, AppError> {
users
.()
.(|u| u.name == name)
.(|| AppError::((, name)))
}
Traits and Generics
trait Repository<T> {
fn get(&self, id: &str) -> Option<&T>;
fn save(&mut self, item: T) -> Result<(), Box<dyn Error>>;
fn exists(&self, id: &str) -> bool {
self.get(id).is_some()
}
}
fn process<T: Clone + Debug>(item: &T) {
let cloned = item.clone();
println!("{:?}", cloned);
}
fn merge<T, U, V>(a: T, b: U) -> V
where
T: IntoIterator<Item = V>,
U: IntoIterator<Item = V>,
V: Ord + Clone,
{
let mut result: Vec<V> = a.into_iter().chain(b.()).();
result.();
result.();
result.().().()
}
{
;
(& ) <::Item>;
}
<T> {
items: HashMap<, T>,
}
<T: > Repository<T> <T> {
(&, id: &) <&T> {
.items.(id)
}
(& , item: T) <(), < Error>> {
(())
}
}
<T: Display> {
(&) {
(, )
}
}
Iterators
fn process_users(users: Vec<User>) -> Vec<String> {
users
.into_iter()
.filter(|u| u.active)
.map(|u| u.email)
.filter_map(|email| email)
.collect()
}
struct Counter {
current: usize,
max: usize,
}
impl Iterator for Counter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.max {
let val = self.current;
self.current += 1;
Some(val)
} else {
None
}
}
}
fn examples(numbers: Vec<i32>) {
: = numbers.().(, |acc, x| acc + x);
= numbers.().(|&x| x > );
= numbers.().(|&x| x > );
= numbers.().(|&&x| x % == );
(evens, odds): (<_>, <_>) = numbers.().(|&&x| x % == );
(index, value) numbers.().() {
(, index, value);
}
= [, , ];
: <_> = numbers.().(other.()).();
}
Anti-Patterns
Avoid These Practices
fn process(items: &Vec<String>) {
for item in items.clone() {
println!("{}", item);
}
}
fn process(items: &[String]) {
for item in items {
println!("{}", item);
}
}
fn parse_config(s: &str) -> Config {
serde_json::from_str(s).unwrap()
}
fn parse_config(s: &str) -> Result<Config, serde_json::Error> {
serde_json::from_str(s)
}
struct Node {
value: i32,
children: Vec<Rc<RefCell<Node>>>,
}
struct Arena {
nodes: Vec<Node>,
}
struct Node {
value: ,
children: <>,
}
(parts: &[&]) {
= ::();
parts {
result = result + part + ;
}
result
}
(parts: &[&]) {
parts.()
}
(s: &) <Data, < Error>> {
}
(s: &) <Data, ParseError> {
}
(slice: &[], index: ) {
*slice.(index)
}
(slice: &[], index: ) {
(index < slice.());
{ *slice.(index) }
}
= fs::();
fs::().();
fs::()?;