rust

Rust programming patterns including ownership, lifetimes, traits, and async programming.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rust" with this command: npx skills add miles990/claude-software-skills/miles990-claude-software-skills-rust

Rust

Overview

Rust programming patterns including ownership, lifetimes, traits, and async programming.

Ownership and Borrowing

Basic Ownership

fn main() { // Ownership transfer (move) let s1 = String::from("hello"); let s2 = s1; // s1 is moved to s2 // println!("{}", s1); // Error: s1 is no longer valid

// Clone for deep copy
let s3 = String::from("hello");
let s4 = s3.clone();
println!("{} {}", s3, s4); // Both valid

// Copy types (stack-only data)
let x = 5;
let y = x; // Copy, not move
println!("{} {}", x, y); // Both valid

}

// Ownership and functions fn takes_ownership(s: String) { println!("{}", s); } // s is dropped here

fn makes_copy(x: i32) { println!("{}", x); } // x goes out of scope, nothing special

fn gives_ownership() -> String { String::from("hello") }

fn takes_and_gives_back(s: String) -> String { s }

Borrowing

// Immutable borrow fn calculate_length(s: &String) -> usize { s.len() } // s goes out of scope but doesn't drop the value

// Mutable borrow fn append_world(s: &mut String) { s.push_str(" world"); }

fn main() { let s = String::from("hello");

// Multiple immutable borrows OK
let r1 = &s;
let r2 = &s;
println!("{} {}", r1, r2);

// Mutable borrow (only one at a time)
let mut s2 = String::from("hello");
let r3 = &mut s2;
r3.push_str(" world");
println!("{}", r3);

// Cannot have mutable and immutable at same time
let mut s3 = String::from("hello");
let r4 = &s3;
// let r5 = &mut s3; // Error!
println!("{}", r4);

}

Lifetimes

// Explicit lifetime annotations fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }

// Struct with lifetime struct Excerpt<'a> { part: &'a str, }

impl<'a> Excerpt<'a> { fn level(&self) -> i32 { 3 }

fn announce_and_return(&#x26;self, announcement: &#x26;str) -> &#x26;str {
    println!("Attention: {}", announcement);
    self.part
}

}

// Multiple lifetimes fn complex<'a, 'b>(x: &'a str, y: &'b str) -> &'a str where 'b: 'a, // 'b outlives 'a { x }

// Static lifetime fn static_string() -> &'static str { "I live forever" }

Structs and Enums

Structs

#[derive(Debug, Clone, PartialEq)] struct User { id: u64, email: String, name: String, active: bool, }

impl User { // Associated function (constructor) fn new(email: String, name: String) -> Self { Self { id: generate_id(), email, name, active: true, } }

// Method
fn deactivate(&#x26;mut self) {
    self.active = false;
}

// Method returning reference
fn email(&#x26;self) -> &#x26;str {
    &#x26;self.email
}

}

// Tuple struct struct Color(u8, u8, u8); struct Point(f64, f64, f64);

// Unit struct struct AlwaysEqual;

Enums

// Basic enum enum Direction { North, South, East, West, }

// Enum with data enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(u8, u8, u8), }

impl Message { fn process(&self) { match self { Message::Quit => println!("Quit"), Message::Move { x, y } => println!("Move to ({}, {})", x, y), Message::Write(text) => println!("Write: {}", text), Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b), } } }

// Result and Option fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("Division by zero")) } else { Ok(a / b) } }

fn find_user(id: u64) -> Option<User> { // ... None }

Traits

// Trait definition trait Summary { fn summarize(&self) -> String;

// Default implementation
fn summarize_author(&#x26;self) -> String {
    String::from("(unknown author)")
}

}

// Implement trait impl Summary for User { fn summarize(&self) -> String { format!("{} ({})", self.name, self.email) } }

// Trait bounds fn notify<T: Summary>(item: &T) { println!("Breaking news: {}", item.summarize()); }

// Multiple trait bounds fn notify_multiple<T: Summary + Clone>(item: &T) { let cloned = item.clone(); println!("{}", cloned.summarize()); }

// where clause fn some_function<T, U>(t: &T, u: &U) -> i32 where T: Summary + Clone, U: Clone + std::fmt::Debug, { // ... 0 }

// Return trait fn create_summarizable() -> impl Summary { User::new( String::from("test@example.com"), String::from("Test"), ) }

// Trait objects (dynamic dispatch) fn process_summaries(items: &[&dyn Summary]) { for item in items { println!("{}", item.summarize()); } }

Error Handling

use std::fs::File; use std::io::{self, Read}; use thiserror::Error;

// Custom error with thiserror #[derive(Error, Debug)] pub enum AppError { #[error("IO error: {0}")] Io(#[from] io::Error),

#[error("Parse error: {0}")]
Parse(#[from] std::num::ParseIntError),

#[error("Not found: {0}")]
NotFound(String),

#[error("Validation error: {field} - {message}")]
Validation { field: String, message: String },

}

// Using Result fn read_file(path: &str) -> Result<String, AppError> { let mut file = File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents) }

// ? operator chains fn read_username_from_file() -> Result<String, io::Error> { let mut username = String::new(); File::open("username.txt")?.read_to_string(&mut username)?; Ok(username) }

// Option handling fn find_and_process(id: u64) -> Option<String> { let user = find_user(id)?; let data = process_user(&user)?; Some(data) }

// Combinators fn get_user_email(id: u64) -> Option<String> { find_user(id) .map(|user| user.email) .filter(|email| !email.is_empty()) }

fn parse_and_double(s: &str) -> Result<i32, std::num::ParseIntError> { s.parse::<i32>().map(|n| n * 2) }

Async Programming

use tokio; use futures::future;

// Async function async fn fetch_data(url: &str) -> Result<String, reqwest::Error> { let response = reqwest::get(url).await?; let body = response.text().await?; Ok(body) }

// Concurrent execution async fn fetch_all(urls: Vec<&str>) -> Vec<Result<String, reqwest::Error>> { let futures: Vec<_> = urls.iter().map(|url| fetch_data(url)).collect(); future::join_all(futures).await }

// Select (race) use tokio::select; use tokio::time::{sleep, Duration};

async fn fetch_with_timeout(url: &str) -> Result<String, &'static str> { select! { result = fetch_data(url) => result.map_err(|_| "fetch error"), _ = sleep(Duration::from_secs(5)) => Err("timeout"), } }

// Spawn tasks async fn process_items(items: Vec<String>) { let handles: Vec<_> = items .into_iter() .map(|item| { tokio::spawn(async move { process_item(&item).await }) }) .collect();

for handle in handles {
    if let Err(e) = handle.await {
        eprintln!("Task failed: {}", e);
    }
}

}

// Streams use futures::stream::{self, StreamExt};

async fn process_stream() { let numbers = stream::iter(vec![1, 2, 3, 4, 5]);

numbers
    .map(|n| async move { n * 2 })
    .buffer_unordered(3)
    .for_each(|n| async move {
        println!("{}", n);
    })
    .await;

}

// Channels use tokio::sync::mpsc;

async fn channel_example() { let (tx, mut rx) = mpsc::channel(32);

tokio::spawn(async move {
    for i in 0..10 {
        tx.send(i).await.unwrap();
    }
});

while let Some(value) = rx.recv().await {
    println!("Received: {}", value);
}

}

Collections and Iterators

use std::collections::{HashMap, HashSet, VecDeque};

// Vec operations let mut vec = vec![1, 2, 3]; vec.push(4); vec.extend([5, 6, 7]); let first = vec.first(); let last = vec.pop();

// HashMap let mut map: HashMap<String, i32> = HashMap::new(); map.insert(String::from("key"), 42); map.entry(String::from("key2")).or_insert(0);

// Iterator methods let numbers = vec![1, 2, 3, 4, 5];

let doubled: Vec<_> = numbers.iter().map(|x| x * 2).collect();

let sum: i32 = numbers.iter().sum();

let evens: Vec<_> = numbers.iter().filter(|x| *x % 2 == 0).collect();

let found = numbers.iter().find(|&&x| x > 3);

let all_positive = numbers.iter().all(|x| *x > 0);

// Chaining let result: i32 = numbers .iter() .filter(|x| *x % 2 == 0) .map(|x| x * 2) .sum();

// Custom iterator struct Counter { count: u32, max: u32, }

impl Iterator for Counter { type Item = u32;

fn next(&#x26;mut self) -> Option&#x3C;Self::Item> {
    if self.count &#x3C; self.max {
        self.count += 1;
        Some(self.count)
    } else {
        None
    }
}

}

Smart Pointers

use std::rc::Rc; use std::cell::RefCell; use std::sync::{Arc, Mutex};

// Box - heap allocation let boxed = Box::new(5); let list = Box::new(Node { value: 1, next: Some(Box::new(Node { value: 2, next: None })), });

// Rc - reference counting let a = Rc::new(5); let b = Rc::clone(&a); let c = Rc::clone(&a); println!("count: {}", Rc::strong_count(&a)); // 3

// RefCell - interior mutability let cell = RefCell::new(5); *cell.borrow_mut() += 1; println!("{}", cell.borrow()); // 6

// Rc<RefCell<T>> - shared mutable state let shared = Rc::new(RefCell::new(vec![1, 2, 3])); let shared2 = Rc::clone(&shared); shared.borrow_mut().push(4); shared2.borrow_mut().push(5);

// Arc - thread-safe Rc let arc = Arc::new(5); let arc2 = Arc::clone(&arc);

// Arc<Mutex<T>> - shared mutable state across threads let counter = Arc::new(Mutex::new(0)); let handles: Vec<> = (0..10) .map(|| { let counter = Arc::clone(&counter); std::thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }) }) .collect();

for handle in handles { handle.join().unwrap(); }

Related Skills

  • [[system-design]] - Systems programming

  • [[desktop-apps]] - Tauri applications

  • [[performance-optimization]] - Low-level optimization

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

game-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

devops-cicd

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

flame-game-dev

No summary provided by upstream source.

Repository SourceNeeds Review