# Rust Patterns

> Rust patterns, ownership best practices, and production-ready code guidelines

- **Type:** Skill
- **Install:** `agentstack add skill-jonathan0823-opencode-config-rust-patterns`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Jonathan0823](https://agentstack.voostack.com/s/jonathan0823)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Jonathan0823](https://github.com/Jonathan0823)
- **Source:** https://github.com/Jonathan0823/opencode-config/tree/main/skills/rust-patterns

## Install

```sh
agentstack add skill-jonathan0823-opencode-config-rust-patterns
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Rust Patterns Skill

## Overview

This skill provides guidelines for writing safe, efficient, and idiomatic Rust code, covering ownership, lifetimes, error handling, and async patterns for production systems with Actix/Tokio.

## Core Principles

### 1. Ownership and Borrowing

```rust
// DO: Use ownership transfer for large data
fn process_data(data: Vec) -> ProcessedData {
    // Takes ownership, no copy
    ProcessedData::from(data)
}

// DO: Borrow for read-only access
fn print_info(data: &[u8]) {
    // Immutable borrow
    println!("{:?}", data);
}

// DO: Mutable borrow for modification
fn update_buffer(buf: &mut Vec) {
    buf.push(0);
}

// DON'T: Create multiple mutable references
let mut data = vec![1, 2, 3];
let ref1 = &mut data;
let ref2 = &mut data; // ERROR!
```

### 2. Lifetimes

```rust
// DO: Explicit lifetimes for function signatures
fn longest(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

// DO: Struct lifetimes
struct Parser {
    input: &'a str,
}

impl Parser {
    fn new(input: &'a str) -> Self {
        Self { input }
    }
    
    fn parse(&self) -> Result {
        Ok(&self.input[..5])
    }
}

// DO: 'static for owned data
const CONFIG: Config = Config {
    timeout: 30,
};
```

### 3. Error Handling

```rust
// DO: Use Result for recoverable errors
fn read_config(path: &str) -> Result {
    let content = fs::read_to_string(path)?;
    let config: Config = serde_json::from_str(&content)?;
    Ok(config)
}

// DO: Custom error types
#[derive(Debug, thiserror::Error)]
enum AppError {
    #[error("io error: {0}")]
    Io(#[from] io::Error),
    
    #[error("parse error: {0}")]
    Parse(#[from] serde_json::Error),
    
    #[error("validation failed: {message}")]
    Validation { message: String },
    
    #[error("not found: {resource}")]
    NotFound { resource: String },
}

type Result = std::result::Result;

// DO: Use ? operator for early returns
fn process_file(path: &str) -> Result {
    let content = fs::read_to_string(path)?; // Early return on error
    let data = parse_content(&content)?;
    validate_data(&data)?;
    Ok(data)
}
```

### 4. Option and Result Combinators

```rust
// DO: Use combinators instead of match where clear
let value = config.get("timeout")
    .and_then(|v| v.parse::().ok())
    .unwrap_or(30);

// DO: map for transformations
let upper = maybe_string.map(|s| s.to_uppercase());

// DO: ok_or for converting Option to Result
let port = env::var("PORT")
    .ok()
    .and_then(|p| p.parse().ok())
    .ok_or(AppError::Validation {
        message: "PORT must be a valid number".into(),
    })?;
```

### 5. Smart Pointers

```rust
// DO: Box for recursive types
enum Node {
    Value(i32),
    Cons(i32, Box),
}

// DO: Rc for shared ownership (single-threaded)
use std::rc::Rc;
let shared_data: Rc> = Rc::new(vec![1, 2, 3]);
let clone1 = Rc::clone(&shared_data);
let clone2 = Rc::clone(&shared_data);

// DO: Arc for thread-safe shared ownership
use std::sync::Arc;
let data: Arc> = Arc::new(vec![1, 2, 3]);

// DO: Mutex/RwLock for interior mutability
use std::sync::{Arc, Mutex};
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
std::thread::spawn(move || {
    let mut num = counter_clone.lock().unwrap();
    *num += 1;
});
```

## Async Patterns (Tokio)

```rust
// DO: Use async/await
async fn fetch_data(url: &str) -> Result, reqwest::Error> {
    let response = reqwest::get(url).await?;
    let bytes = response.bytes().await?;
    Ok(bytes.to_vec())
}

// DO: Concurrent execution with join!
use futures::join;

async fn fetch_multiple() -> Result, Vec), Error> {
    let (result1, result2) = join!(
        fetch_data("https://api1.example.com"),
        fetch_data("https://api2.example.com"),
    );
    Ok((result1?, result2?))
}

// DO: Spawn tasks for parallel work
async fn process_batch(items: Vec) -> Vec> {
    let handles: Vec = items
        .into_iter()
        .map(|item| {
            tokio::spawn(async move {
                process_item(item).await
            })
        })
        .collect();
    
    let mut results = Vec::new();
    for handle in handles {
        results.push(handle.await.unwrap());
    }
    results
}

// DO: Use channels for communication
use tokio::sync::mpsc;

async fn worker(mut rx: mpsc::Receiver) {
    while let Some(job) = rx.recv().await {
        process_job(job).await;
    }
}
```

## Actix Web Patterns

```rust
// DO: Application state with Arc
struct AppState {
    db: Arc,
    config: Arc,
}

async fn handler(data: web::Data) -> impl Responder {
    let result = data.db.query().await;
    HttpResponse::Ok().json(result)
}

// DO: Extractors for request data
#[derive(Deserialize)]
struct CreateUserRequest {
    name: String,
    email: String,
}

async fn create_user(
    data: web::Data,
    req: web::Json,
) -> Result {
    let user = data.db.create_user(req.into_inner()).await?;
    Ok(HttpResponse::Created().json(user))
}

// DO: Custom middleware
fn auth_middleware() -> impl Transform {
    fn transform(service: S) -> AuthMiddleware {
        AuthMiddleware { service }
    }
    
    middleware::from_fn(|req, srv| async move {
        if !is_authenticated(&req) {
            return Err(ErrorUnauthorized("Unauthorized"));
        }
        srv.call(req).await
    })
}
```

## Structs and Enums

```rust
// DO: Builder pattern for complex structs
#[derive(Default)]
struct ConfigBuilder {
    host: Option,
    port: Option,
    workers: Option,
}

impl ConfigBuilder {
    fn host(mut self, host: impl Into) -> Self {
        self.host = Some(host.into());
        self
    }
    
    fn port(mut self, port: u16) -> Self {
        self.port = Some(port);
        self
    }
    
    fn build(self) -> Config {
        Config {
            host: self.host.unwrap_or_else(|| "localhost".into()),
            port: self.port.unwrap_or(8080),
            workers: self.workers.unwrap_or(4),
        }
    }
}

// DO: Use enums for state machines
enum ConnectionState {
    Disconnected,
    Connecting { since: Instant },
    Connected { socket: TcpStream },
    Error { reason: String },
}

impl ConnectionState {
    fn is_connected(&self) -> bool {
        matches!(self, ConnectionState::Connected { .. })
    }
}
```

## Testing

```rust
// DO: Unit tests in the same file
#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_async_function() {
        let result = async_function().await;
        assert!(result.is_ok());
    }
    
    #[test]
    fn test_with_fixture() {
        let fixture = create_test_fixture();
        let result = process(fixture);
        assert_eq!(result, expected);
    }
}

// DO: Mock with traits
trait Database {
    async fn query(&self) -> Result, Error>;
}

struct MockDb {
    results: Vec,
}

#[async_trait]
impl Database for MockDb {
    async fn query(&self) -> Result, Error> {
        Ok(self.results.clone())
    }
}
```

## When to Use

Use this skill when:
- Writing or reviewing Rust code
- Handling complex ownership/lifetime scenarios
- Implementing async/await code
- Building web services with Actix
- Writing concurrent/parallel code
- Designing Rust APIs
- Refactoring for performance

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Jonathan0823](https://github.com/Jonathan0823)
- **Source:** [Jonathan0823/opencode-config](https://github.com/Jonathan0823/opencode-config)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jonathan0823-opencode-config-rust-patterns
- Seller: https://agentstack.voostack.com/s/jonathan0823
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
