# Advanced Rust Patterns: Moderate to Difficult Use Cases

> When a method receives two references with potentially different lifetimes and returns a reference, the compiler needs explicit lifetime annotations to determine which input lifetime the output is tied to.

- Skill: `tools-only/advanced-rust-patterns-moderate-to-difficult-use-cases` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/advanced-rust-patterns-moderate-to-difficult-use-cases`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/advanced-rust-patterns-moderate-to-difficult-use-cases/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/advanced-rust-patterns-moderate-to-difficult-use-cases

---

# Advanced Rust Patterns: Moderate to Difficult Use Cases
**Research Date:** 2025-12-01
**Focus:** Ownership, Traits, Async, Error Handling, Type-Safe Design
**Complexity Level:** Moderate to Difficult

---

## Table of Contents
1. [Ownership & Borrowing Mastery](#1-ownership--borrowing-mastery)
2. [Trait System](#2-trait-system)
3. [Async/Concurrency](#3-asyncconcurrency)
4. [Error Handling](#4-error-handling)
5. [Type-Safe Design](#5-type-safe-design)

---

## 1. Ownership & Borrowing Mastery

### 1.1 Advanced Lifetime Patterns

**Pattern Name:** Explicit Lifetime Annotations with Multiple References
**Complexity:** ⭐⭐⭐ Moderate
**Safety Guarantees:** Prevents dangling references, ensures memory safety

#### Problem Solved
When a method receives two references with potentially different lifetimes and returns a reference, the compiler needs explicit lifetime annotations to determine which input lifetime the output is tied to.

#### Code Example

```rust
struct ContentManager {
    content: String,
}

impl ContentManager {
    // Explicit lifetime annotation required
    fn get_content_or_default<'a, 'b>(
        &'a self,
        default: &'b str,
    ) -> &'a str
    where
        'b: 'a, // 'b must outlive 'a
    {
        if self.content.is_empty() {
            // Cannot return default here due to lifetime mismatch
            // This forces us to return from self
            &self.content
        } else {
            &self.content
        }
    }

    // Better pattern: return owned when necessary
    fn get_content_or_default_owned(&self, default: &str) -> String {
        if self.content.is_empty() {
            default.to_string()
        } else {
            self.content.clone()
        }
    }
}

// Advanced: Generic lifetime bounds with traits
trait Cache<'a, T> {
    fn get(&'a self, key: &str) -> Option<&'a T>;
}

struct MemoryCache<T> {
    data: std::collections::HashMap<String, T>,
}

impl<'a, T> Cache<'a, T> for MemoryCache<T> {
    fn get(&'a self, key: &str) -> Option<&'a T> {
        self.data.get(key)
    }
}
```

#### Lifetime Elision Rules

**Rule 1:** Each reference parameter gets its own lifetime
```rust
fn foo(x: &i32, y: &i32) // becomes
fn foo<'a, 'b>(x: &'a i32, y: &'b i32)
```

**Rule 2:** If there is one input lifetime, it's assigned to all outputs
```rust
fn process(input: &str) -> &str // becomes
fn process<'a>(input: &'a str) -> &'a str
```

**Rule 3:** If there are multiple input lifetimes but one is `&self`, the output gets `self`'s lifetime
```rust
impl Foo {
    fn method(&self, other: &str) -> &str // becomes
    fn method<'a, 'b>(&'a self, other: &'b str) -> &'a str
}
```

**When to Use:**
- When returning references from structs with multiple lifetime dependencies
- When elision rules cannot infer the correct lifetime relationship
- When building generic cache or reference-holding data structures

**Borrow Checker Issues Solved:**
- "borrowed value does not live long enough"
- "cannot infer an appropriate lifetime"
- "lifetime may not live long enough"

**Performance:** Zero-cost abstraction - lifetimes are compile-time only

---

### 1.2 Interior Mutability Patterns

**Pattern Name:** RefCell<T> and Cell<T> for Single-Threaded Interior Mutability
**Complexity:** ⭐⭐⭐ Moderate
**Safety Guarantees:** Runtime borrow checking, single-threaded safety

#### Problem Solved
Allows mutation through shared references when the compiler cannot prove safety at compile time, enabling patterns like multiple owners with mutation or circular references.

#### Code Example

```rust
use std::cell::{Cell, RefCell};
use std::rc::Rc;

// Example 1: Graph with RefCell for interior mutability
#[derive(Debug)]
struct Node {
    value: i32,
    neighbors: RefCell<Vec<Rc<Node>>>,
}

impl Node {
    fn new(value: i32) -> Rc<Self> {
        Rc::new(Node {
            value,
            neighbors: RefCell::new(Vec::new()),
        })
    }

    fn add_neighbor(&self, neighbor: Rc<Node>) {
        // Mutate through shared reference
        self.neighbors.borrow_mut().push(neighbor);
    }

    fn neighbors_count(&self) -> usize {
        self.neighbors.borrow().len()
    }
}

// Example 2: Mock object pattern with RefCell
struct MockDatabase {
    call_count: RefCell<usize>,
    responses: RefCell<Vec<String>>,
}

impl MockDatabase {
    fn new() -> Self {
        MockDatabase {
            call_count: RefCell::new(0),
            responses: RefCell::new(Vec::new()),
        }
    }

    fn query(&self, _sql: &str) -> String {
        // Mutate call count through shared reference
        *self.call_count.borrow_mut() += 1;

        // Return mock response
        self.responses
            .borrow_mut()
            .pop()
            .unwrap_or_else(|| "default".to_string())
    }

    fn times_called(&self) -> usize {
        *self.call_count.borrow()
    }
}

// Example 3: Cell for Copy types
struct Metrics {
    request_count: Cell<u64>,
    error_count: Cell<u64>,
}

impl Metrics {
    fn new() -> Self {
        Metrics {
            request_count: Cell::new(0),
            error_count: Cell::new(0),
        }
    }

    fn record_request(&self) {
        // No borrow_mut needed for Cell
        self.request_count.set(self.request_count.get() + 1);
    }

    fn record_error(&self) {
        self.error_count.set(self.error_count.get() + 1);
    }
}
```

#### RefCell vs Cell vs Mutex

| Type | Thread Safety | Borrow Check | Copy Types Only | Runtime Cost |
|------|--------------|--------------|-----------------|--------------|
| `Cell<T>` | ❌ No | No borrowing | ✅ Yes | Lowest |
| `RefCell<T>` | ❌ No | ✅ Runtime | ❌ No | Low (runtime checks) |
| `Mutex<T>` | ✅ Yes | ✅ Runtime | ❌ No | Higher (locking) |

**When to Use:**
- **Cell<T>:** For Copy types (integers, booleans) that need mutation through shared references
- **RefCell<T>:** For non-Copy types in single-threaded scenarios (UI, tests, graphs)
- **Rc<RefCell<T>>:** Multiple ownership + interior mutability (graphs, trees)

**Borrow Checker Issues Solved:**
- "cannot borrow as mutable" when only shared reference available
- Circular reference patterns (with Weak to prevent leaks)
- Mock objects in tests that need mutation

**Performance:**
- Cell<T>: Zero overhead
- RefCell<T>: Small runtime cost for borrow tracking
- Panics at runtime if borrow rules violated

**Common Pitfall:**
```rust
// DANGER: This will panic!
let data = RefCell::new(vec![1, 2, 3]);
let borrow1 = data.borrow_mut(); // OK
let borrow2 = data.borrow_mut(); // PANIC: already borrowed
```

---

### 1.3 Smart Pointer Patterns: Arc<Mutex<T>> vs Arc<RwLock<T>>

**Pattern Name:** Thread-Safe Shared Ownership with Controlled Mutation
**Complexity:** ⭐⭐⭐⭐ Difficult
**Safety Guarantees:** Thread-safe sharing, prevents data races

#### Problem Solved
Enables multiple threads to share and mutate data safely, choosing the right synchronization primitive based on read/write ratio.

#### Code Example

```rust
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use std::time::Duration;

// Example 1: Arc<Mutex<T>> for balanced read/write
#[derive(Clone)]
struct Counter {
    value: Arc<Mutex<u64>>,
}

impl Counter {
    fn new() -> Self {
        Counter {
            value: Arc::new(Mutex::new(0)),
        }
    }

    fn increment(&self) {
        let mut val = self.value.lock().unwrap();
        *val += 1;
    }

    fn get(&self) -> u64 {
        *self.value.lock().unwrap()
    }
}

// Example 2: Arc<RwLock<T>> for read-heavy workloads
#[derive(Clone)]
struct Cache {
    data: Arc<RwLock<std::collections::HashMap<String, String>>>,
}

impl Cache {
    fn new() -> Self {
        Cache {
            data: Arc::new(RwLock::new(std::collections::HashMap::new())),
        }
    }

    // Many threads can read simultaneously
    fn get(&self, key: &str) -> Option<String> {
        let read_guard = self.data.read().unwrap();
        read_guard.get(key).cloned()
    }

    // Only one thread can write
    fn set(&self, key: String, value: String) {
        let mut write_guard = self.data.write().unwrap();
        write_guard.insert(key, value);
    }
}

// Example 3: Practical multi-threaded server pattern
struct Server {
    connections: Arc<RwLock<Vec<String>>>,
    stats: Arc<Mutex<ServerStats>>,
}

struct ServerStats {
    requests: u64,
    errors: u64,
}

impl Server {
    fn new() -> Self {
        Server {
            connections: Arc::new(RwLock::new(Vec::new())),
            stats: Arc::new(Mutex::new(ServerStats {
                requests: 0,
                errors: 0,
            })),
        }
    }

    fn add_connection(&self, conn: String) {
        let mut conns = self.connections.write().unwrap();
        conns.push(conn);
    }

    fn get_connection_count(&self) -> usize {
        // Read lock allows multiple concurrent reads
        self.connections.read().unwrap().len()
    }

    fn record_request(&self) {
        let mut stats = self.stats.lock().unwrap();
        stats.requests += 1;
    }

    fn spawn_workers(&self, count: usize) {
        for i in 0..count {
            let stats = Arc::clone(&self.stats);
            thread::spawn(move || {
                for _ in 0..100 {
                    let mut s = stats.lock().unwrap();
                    s.requests += 1;
                    thread::sleep(Duration::from_millis(10));
                }
            });
        }
    }
}
```

#### Performance Characteristics

**Mutex:**
- Consistent performance for reads and writes
- Lower overhead for single operation
- Better for write-heavy or balanced workloads
- No writer starvation

**RwLock:**
- Excellent for read-heavy workloads (90%+ reads)
- Higher overhead per operation
- Multiple concurrent readers
- Can suffer from writer starvation
- Performance degrades significantly with many writes

**Benchmark Results (typical):**
```
Workload: 90% reads, 10% writes
- Arc<Mutex<T>>:   ~500ns per operation
- Arc<RwLock<T>>:  ~100ns per operation (5x faster)

Workload: 50% reads, 50% writes
- Arc<Mutex<T>>:   ~500ns per operation
- Arc<RwLock<T>>:  ~600ns per operation (slower)
```

**When to Use:**

**Arc<Mutex<T>>:**
- Default choice for shared mutable state
- Balanced read/write ratio (>20% writes)
- Simple shared counters or flags
- When in doubt, start here

**Arc<RwLock<T>>:**
- Read-heavy workloads (>80% reads)
- Shared caches
- Configuration data that rarely changes
- Large data structures where read operations are expensive

**Arc<Atomic*>:**
- Simple atomic types (integers, booleans)
- Lock-free counters
- Highest performance for simple values

**Borrow Checker Issues Solved:**
- "cannot move out of shared reference"
- "cannot borrow as mutable in multiple threads"
- Data race prevention at compile time

**Common Pitfalls:**

```rust
// DEADLOCK: Don't lock multiple mutexes in different orders
let lock1 = mutex1.lock().unwrap();
let lock2 = mutex2.lock().unwrap(); // Thread A
// vs
let lock2 = mutex2.lock().unwrap();
let lock1 = mutex1.lock().unwrap(); // Thread B - DEADLOCK!

// POISON: Handle panics in locked sections
match mutex.lock() {
    Ok(guard) => { /* use guard */ },
    Err(poisoned) => {
        // Mutex poisoned due to panic while locked
        let guard = poisoned.into_inner(); // Recover if safe
    }
}
```

---

## 2. Trait System

### 2.1 Associated Types vs Generic Parameters

**Pattern Name:** Type Projection vs Parameterization
**Complexity:** ⭐⭐⭐⭐ Difficult
**Safety Guarantees:** Type-safe abstraction, prevents ambiguous implementations

#### Problem Solved
Distinguishes between traits that should have multiple implementations per type (generics) versus single canonical implementation (associated types).

#### Code Example

```rust
// GENERIC TYPE PARAMETER: Multiple implementations possible
trait From<T> {
    fn from(value: T) -> Self;
}

// Can implement From for many types
impl From<u8> for u32 {
    fn from(value: u8) -> u32 {
        value as u32
    }
}

impl From<u16> for u32 {
    fn from(value: u16) -> u32 {
        value as u32
    }
}

// ASSOCIATED TYPE: Only one implementation per type
trait Iterator {
    type Item; // Associated type

    fn next(&mut self) -> Option<Self::Item>;
}

// Counter can only iterate over one type
struct Counter {
    count: u32,
}

impl Iterator for Counter {
    type Item = u32; // Can't implement Iterator<String> for Counter

    fn next(&mut self) -> Option<Self::Item> {
        self.count += 1;
        Some(self.count)
    }
}

// Example: Choosing between approaches
// BAD: Iterator with generic would allow nonsense
trait BadIterator<T> {
    fn next(&mut self) -> Option<T>;
}

// This compiles but makes no sense:
// impl BadIterator<String> for Counter { ... }
// impl BadIterator<u32> for Counter { ... }
// Now counter.next() is ambiguous!

// Example: Conversion trait with associated type
trait TryParse {
    type Output;
    type Error;

    fn try_parse(s: &str) -> Result<Self::Output, Self::Error>;
}

struct JsonParser;

impl TryParse for JsonParser {
    type Output = serde_json::Value;
    type Error = serde_json::Error;

    fn try_parse(s: &str) -> Result<Self::Output, Self::Error> {
        serde_json::from_str(s)
    }
}

// Advanced: Generic + associated type combo
trait Graph {
    type Node;
    type Edge;

    fn neighbors(&self, node: &Self::Node) -> Vec<Self::Edge>;
}

trait GenericGraph<N, E> {
    fn neighbors(&self, node: &N) -> Vec<E>;
}

// Associated types better: each graph has one node/edge type
// Generic would allow Graph<String, i32> AND Graph<u32, String> for same type
```

#### Decision Matrix

| Use Associated Types When | Use Generic Parameters When |
|---------------------------|----------------------------|
| ✅ Only one logical implementation per type | ✅ Multiple implementations make sense |
| ✅ Output type determined by input type | ✅ Caller chooses the type |
| ✅ Trait represents identity/capability | ✅ Trait represents conversion/transformation |
| Example: `Iterator::Item` | Example: `From<T>` |
| Example: `Deref::Target` | Example: `Add<Rhs>` |

**When to Use:**
- **Associated Types:** Iterator, Deref, Future (one obvious output type)
- **Generic Parameters:** From/Into, Add/Sub (multiple conversions make sense)

**Borrow Checker Issues Solved:**
- Prevents ambiguous type inference
- Enforces "one true implementation" at type level
- Cleaner APIs without turbofish (`::<>`) syntax

**Performance:** Zero-cost - both approaches are compile-time only

---

### 2.2 Trait Objects (dyn Trait)

**Pattern Name:** Dynamic Dispatch with Type Erasure
**Complexity:** ⭐⭐⭐⭐ Difficult
**Safety Guarantees:** Object-safe traits, runtime polymorphism

#### Problem Solved
Enables heterogeneous collections and runtime polymorphism when concrete types aren't known at compile time.

#### Code Example

```rust
// Example 1: Object-safe trait for plugin system
trait Plugin: Send + Sync {
    fn name(&self) -> &str;
    fn execute(&self, input: &str) -> String;
}

struct UppercasePlugin;
impl Plugin for UppercasePlugin {
    fn name(&self) -> &str { "uppercase" }
    fn execute(&self, input: &str) -> String {
        input.to_uppercase()
    }
}

struct ReversePlugin;
impl Plugin for ReversePlugin {
    fn name(&self) -> &str { "reverse" }
    fn execute(&self, input: &str) -> String {
        input.chars().rev().collect()
    }
}

struct PluginManager {
    plugins: Vec<Box<dyn Plugin>>,
}

impl PluginManager {
    fn new() -> Self {
        PluginManager { plugins: Vec::new() }
    }

    fn register(&mut self, plugin: Box<dyn Plugin>) {
        self.plugins.push(plugin);
    }

    fn execute_all(&self, input: &str) -> Vec<String> {
        self.plugins
            .iter()
            .map(|p| p.execute(input))
            .collect()
    }
}

// Example 2: GUI rendering with trait objects
trait Drawable {
    fn draw(&self, canvas: &mut Canvas);
    fn bounds(&self) -> Rectangle;
}

struct Circle { x: f64, y: f64, radius: f64 }
struct Rectangle { x: f64, y: f64, width: f64, height: f64 }

impl Drawable for Circle {
    fn draw(&self, canvas: &mut Canvas) {
        canvas.draw_circle(self.x, self.y, self.radius);
    }
    fn bounds(&self) -> Rectangle {
        Rectangle {
            x: self.x - self.radius,
            y: self.y - self.radius,
            width: self.radius * 2.0,
            height: self.radius * 2.0,
        }
    }
}

struct Scene {
    objects: Vec<Box<dyn Drawable>>,
}

impl Scene {
    fn render(&self, canvas: &mut Canvas) {
        for obj in &self.objects {
            obj.draw(canvas); // Dynamic dispatch
        }
    }
}

// Example 3: Object-safe vs NOT object-safe
// OBJECT-SAFE ✅
trait Logger {
    fn log(&self, message: &str);
}

// NOT OBJECT-SAFE ❌
trait BadTrait {
    fn generic_method<T>(&self, value: T); // ❌ Generic methods
    fn returns_self() -> Self; // ❌ Returns Self
    fn sized_bound(&self) where Self: Sized; // ❌ Sized bound
}

// Can't do: Box<dyn BadTrait> - Compile error!

// Example 4: Trait object with lifetime bounds
trait Handler<'a> {
    fn handle(&self, data: &'a str) -> String;
}

struct Processor {
    handlers: Vec<Box<dyn for<'a> Handler<'a>>>, // Higher-rank trait bound
}
```

#### Object Safety Rules

A trait is **object-safe** if:
1. ✅ No generic methods
2. ✅ No associated functions that return `Self`
3. ✅ No `Self: Sized` bounds
4. ✅ Methods use `&self`, `&mut self`, or `Box<Self>`

**Static vs Dynamic Dispatch:**

```rust
// Static dispatch (monomorphization)
fn process_static<T: Plugin>(plugin: &T, input: &str) -> String {
    plugin.execute(input) // Inlined, fast, larger binary
}

// Dynamic dispatch (vtable)
fn process_dynamic(plugin: &dyn Plugin, input: &str) -> String {
    plugin.execute(input) // Pointer indirection, smaller binary
}
```

**Performance Characteristics:**

| Aspect | Static Dispatch | Dynamic Dispatch |
|--------|----------------|------------------|
| Call overhead | None (inlined) | Vtable lookup |
| Binary size | Larger (copies) | Smaller |
| Flexibility | Compile-time only | Runtime composition |
| Speed | Faster (~2-3ns) | Slower (~5-7ns) |

**When to Use:**
- Heterogeneous collections (different types in same Vec)
- Plugin systems
- Dependency injection
- GUI frameworks
- When you can't know types at compile time

**Alternatives:**
- Enum dispatch (faster, but closed set of types)
- Generic parameters (fastest, but monomorphizes)

---

### 2.3 Newtype Pattern and Orphan Rule

**Pattern Name:** Type Wrapper for Trait Implementation
**Complexity:** ⭐⭐⭐ Moderate
**Safety Guarantees:** Orphan rule compliance, type safety

#### Problem Solved
Allows implementing foreign traits on foreign types by wrapping them in a local newtype, bypassing the orphan rule while maintaining type safety.

#### Code Example

```rust
use std::fmt;

// PROBLEM: Can't implement foreign trait on foreign type
// impl fmt::Display for Vec<i32> {} // ❌ Orphan rule violation!

// SOLUTION: Newtype pattern
struct MyVec(Vec<i32>);

impl fmt::Display for MyVec {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[")?;
        for (i, item) in self.0.iter().enumerate() {
            if i > 0 { write!(f, ", ")?; }
            write!(f, "{}", item)?;
        }
        write!(f, "]")
    }
}

// Example 2: Deref for transparent access
use std::ops::Deref;

impl Deref for MyVec {
    type Target = Vec<i32>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

// Now MyVec can use Vec methods!
let mut vec = MyVec(vec![1, 2, 3]);
vec.push(4); // Works via Deref coercion

// Example 3: Stronger type safety with newtype
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct UserId(u64);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct PostId(u64);

fn get_user(id: UserId) -> User { /* ... */ }
fn get_post(id: PostId) -> Post { /* ... */ }

// Type safety prevents bugs:
let user_id = UserId(42);
let post_id = PostId(42);

get_user(user_id); // ✅ OK
// get_user(post_id); // ❌ Compile error!

// Example 4: Zero-cost newtype with transparent representation
#[repr(transparent)]
struct Meters(f64);

impl Meters {
    fn to_feet(&self) -> f64 {
        self.0 * 3.28084
    }
}

// Example 5: Implementing standard traits for ergonomics
impl From<Vec<i32>> for MyVec {
    fn from(vec: Vec<i32>) -> Self {
        MyVec(vec)
    }
}

impl From<MyVec> for Vec<i32> {
    fn from(wrapper: MyVec) -> Self {
        wrapper.0
    }
}

// Now conversions are easy
let vec = vec![1, 2, 3];
let my_vec: MyVec = vec.into();
let back: Vec<i32> = my_vec.into();
```

#### Orphan Rule Explained

**Rule:** You can implement a trait for a type only if either:
- The trait is defined in your crate, OR
- The type is defined in your crate

**Examples:**

```rust
// ✅ ALLOWED: Our trait, foreign type
trait MyTrait {}
impl MyTrait for Vec<i32> {}

// ✅ ALLOWED: Foreign trait, our type
struct MyType;
impl std::fmt::Display for MyType { /* ... */ }

// ❌ FORBIDDEN: Foreign trait, foreign type
// impl std::fmt::Display for Vec<i32> {} // Orphan rule!

// ✅ WORKAROUND: Newtype pattern
struct Wrapper(Vec<i32>);
impl std::fmt::Display for Wrapper { /* ... */ }
```

**When to Use:**
- Implementing foreign traits on foreign types
- Type-safe wrappers (UserId vs raw integers)
- Domain modeling with stronger types
- Adding trait implementations to external types

**Performance:**
- `#[repr(transparent)]` guarantees zero-cost
- Deref coercion provides transparent access
- No runtime overhead

---

### 2.4 Blanket Implementations

**Pattern Name:** Generic Trait Implementation for All Matching Types
**Complexity:** ⭐⭐⭐⭐ Difficult
**Safety Guarantees:** Coherence, automatic implementations

#### Problem Solved
Provides automatic trait implementations for any type that satisfies certain constraints, reducing code duplication and enabling powerful abstractions.

#### Code Example

```rust
// Example 1: Classic From/Into blanket implementation
// From standard library:
impl<T, U> Into<U> for T
where
    U: From<T>,
{
    fn into(self) -> U {
        U::from(self)
    }
}

// This means: implement From, get Into for free!
struct Meters(f64);
struct Feet(f64);

impl From<Meters> for Feet {
    fn from(m: Meters) -> Feet {
        Feet(m.0 * 3.28084)
    }
}

// Automatically available:
let meters = Meters(10.0);
let feet: Feet = meters.into(); // Works via blanket impl!

// Example 2: Custom blanket implementation
trait ToJson {
    fn to_json(&self) -> String;
}

// Blanket impl for all types that implement Display
impl<T: std::fmt::Display> ToJson for T {
    fn to_json(&self) -> String {
        format!("\"{}\"", self)
    }
}

// Now all Display types get to_json for free
let num = 42;
println!("{}", num.to_json()); // "42"

// Example 3: Reference blanket implementations
trait Processable {
    fn process(&self) -> String;
}

struct Data(String);

impl Processable for Data {
    fn process(&self) -> String {
        self.0.to_uppercase()
    }
}

// Blanket impl for references
impl<T: Processable> Processable for &T {
    fn process(&self) -> String {
        (*self).process()
    }
}

// Blanket impl for boxes
impl<T: Processable> Processable for Box<T> {
    fn process(&self) -> String {
        (**self).process()
    }
}

// Example 4: Advanced - conditional blanket implementation
trait Summarize {
    fn summarize(&self) -> String;
}

// Only implement for types that are Debug + Clone
impl<T> Summarize for T
where
    T: std::fmt::Debug + Clone,
{
    fn summarize(&self) -> String {
        format!("{:?}", self)
    }
}

// Example 5: Coherence rules prevent conflicts
trait MyTrait {
    fn do_thing(&self);
}

// ❌ CONFLICT: Can't have overlapping blanket impls
// impl<T> MyTrait for T { ... }
// impl<T: Clone> MyTrait for T { ... } // Compile error!

// ✅ OK: Non-overlapping implementations
impl MyTrait for i32 { /* ... */ }
impl MyTrait for String { /* ... */ }
```

#### Coherence Rules

**Rust enforces coherence:** For any trait + type combination, there must be **at most one** implementation.

**Key Rules:**
1. No two blanket implementations may overlap
2. Specific implementations override blanket implementations
3. Foreign trait + foreign type = can't implement (orphan rule)

**Common Blanket Implementation Patterns:**

```rust
// Pattern 1: Implement for references
impl<T: MyTrait + ?Sized> MyTrait for &T { /* ... */ }
impl<T: MyTrait + ?Sized> MyTrait for &mut T { /* ... */ }
impl<T: MyTrait + ?Sized> MyTrait for Box<T> { /* ... */ }

// Pattern 2: Error conversion
impl<T, E> From<E> for Result<T, E> {
    fn from(err: E) -> Self {
        Err(err)
    }
}

// Pattern 3: Optional conversion
impl<T> From<T> for Option<T> {
    fn from(val: T) -> Self {
        Some(val)
    }
}
```

**When to Use:**
- Automatic trait propagation (From → Into)
- Implementing for reference types (&T, &mut T, Box<T>)
- Generic conversions and utilities
- Framework-level abstractions

**Performance:** Zero-cost - resolved at compile time

---

## 3. Async/Concurrency

### 3.1 Tokio Runtime Patterns

**Pattern Name:** Async Runtime Management and Task Spawning
**Complexity:** ⭐⭐⭐ Moderate
**Safety Guarantees:** Send + Sync enforcement, structured concurrency

#### Problem Solved
Provides efficient cooperative multitasking for I/O-bound operations with proper async/await patterns and runtime management.

#### Code Example

```rust
use tokio::runtime::Runtime;
use tokio::task;
use std::time::Duration;

// Example 1: Different runtime configurations
fn main() {
    // Multi-threaded runtime (default)
    let rt = Runtime::new().unwrap();

    rt.block_on(async {
        println!("Running on multi-threaded runtime");
    });

    // Current thread runtime (single-threaded)
    let rt = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(async {
        println!("Single-threaded runtime");
    });

    // Custom configured runtime
    let rt = tokio::runtime::Builder::new_multi_thread()
        .worker_threads(4)
        .thread_name("my-pool")
        .thread_stack_size(3 * 1024 * 1024)
        .enable_all()
        .build()
        .unwrap();
}

// Example 2: Task spawning patterns
#[tokio::main]
async fn main() {
    // Spawn tasks with JoinHandle
    let handle1 = task::spawn(async {
        tokio::time::sleep(Duration::from_secs(1)).await;
        "task 1 complete"
    });

    let handle2 = task::spawn(async {
        tokio::time::sleep(Duration::from_secs(2)).await;
        "task 2 complete"
    });

    // Wait for both
    let (result1, result2) = tokio::join!(handle1, handle2);
    println!("{:?}, {:?}", result1, result2);
}

// Example 3: Blocking task pattern
#[tokio::main]
async fn main() {
    // DON'T block the async runtime
    // ❌ task::spawn(async { std::thread::sleep(...) }); // Blocks thread!

    // ✅ Use spawn_blocking for CPU-intensive work
    let result = task::spawn_blocking(|| {
        // This runs on a dedicated thread pool
        expensive_cpu_work()
    }).await.unwrap();

    println!("Result: {}", result);
}

fn expensive_cpu_work() -> u64 {
    (0..1_000_000).sum()
}

// Example 4: Practical async server pattern
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    println!("Server listening on port 8080");

    loop {
        let (mut socket, addr) = listener.accept().await?;

        // Spawn a task per connection
        task::spawn(async move {
            let mut buf = [0; 1024];

            match socket.read(&mut buf).await {
                Ok(n) if n == 0 => return, // Connection closed
                Ok(n) => {
                    // Echo back
                    if let Err(e) = socket.write_all(&buf[0..n]).await {
                        eprintln!("Failed to write to {}: {}", addr, e);
                    }
                }
                Err(e) => {
                    eprintln!("Failed to read from {}: {}", addr, e);
                }
            }
        });
    }
}

// Example 5: JoinSet for dynamic task collection
use tokio::task::JoinSet;

#[tokio::main]
async fn main() {
    let mut set = JoinSet::new();

    // Dynamically spawn tasks
    for i in 0..10 {
        set.spawn(async move {
            tokio::time::sleep(Duration::from_millis(i * 100)).await;
            i * 2
        });
    }

    // Collect results as they complete
    while let Some(res) = set.join_next().await {
        match res {
            Ok(value) => println!("Task completed: {}", value),
            Err(e) => eprintln!("Task failed: {}", e),
        }
    }
}
```

#### Runtime Selection Guide

| Runtime Type | Use Case | Thread Count | Overhead |
|--------------|----------|--------------|----------|
| `#[tokio::main]` | Default choice | CPU count | Medium |
| `new_multi_thread()` | High concurrency | Configurable | Medium |
| `new_current_thread()` | Tests, simple apps | 1 | Low |
| `spawn_blocking()` | CPU-bound work | Dedicated pool | Higher |

**When to Use:**
- **Multi-threaded:** I/O-bound servers, network apps
- **Current thread:** Tests, single-threaded environments, WASM
- **spawn_blocking:** File I/O, CPU-intensive computation, synchronous APIs

**Performance Characteristics:**
- Task spawning: ~1-2μs overhead
- Context switching: ~50-100ns
- Much lighter than OS threads (can spawn 100k+ tasks)

---

### 3.2 Graceful Shutdown Patterns

**Pattern Name:** Coordinated Async Task Termination
**Complexity:** ⭐⭐⭐⭐ Difficult
**Safety Guarantees:** No data loss, clean resource cleanup

#### Problem Solved
Coordinates shutdown of multiple async tasks, ensures cleanup operations complete, and prevents data loss during application termination.

#### Code Example

```rust
use tokio::signal;
use tokio::sync::broadcast;
use tokio_util::sync::CancellationToken;
use std::time::Duration;

// Example 1: Signal-based shutdown
#[tokio::main]
async fn main() {
    let (shutdown_tx, mut shutdown_rx) = broadcast::channel(1);

    // Spawn worker tasks
    for i in 0..5 {
        let mut shutdown = shutdown_tx.subscribe();
        tokio::spawn(async move {
            loop {
                tokio::select! {
                    _ = shutdown.recv() => {
                        println!("Worker {} shutting down gracefully", i);
                        // Cleanup operations
                        tokio::time::sleep(Duration::from_millis(100)).await;
                        println!("Worker {} finished cleanup", i);
                        break;
                    }
                    _ = tokio::time::sleep(Duration::from_secs(1)) => {
                        println!("Worker {} doing work", i);
                    }
                }
            }
        });
    }

    // Wait for shutdown signal
    signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
    println!("Shutdown signal received");

    // Send shutdown signal to all workers
    let _ = shutdown_tx.send(());

    // Wait a bit for cleanup
    tokio::time::sleep(Duration::from_millis(500)).await;
    println!("Application terminated");
}

// Example 2: CancellationToken pattern (recommended)
#[tokio::main]
async fn main() {
    let token = CancellationToken::new();

    // Spawn workers with cloned tokens
    let mut handles = vec![];
    for i in 0..5 {
        let token = token.clone();
        let handle = tokio::spawn(async move {
            loop {
                tokio::select! {
                    _ = token.cancelled() => {
                        println!("Worker {} received shutdown", i);
                        // Perform cleanup
                        flush_data(i).await;
                        break;
                    }
                    _ = tokio::time::sleep(Duration::from_secs(1)) => {
                        println!("Worker {} processing", i);
                    }
                }
            }
        });
        handles.push(handle);
    }

    // Wait for signal
    signal::ctrl_c().await.unwrap();
    println!("Initiating graceful shutdown...");

    // Cancel all tasks
    token.cancel();

    // Wait for all workers to finish
    for handle in handles {
        let _ = handle.await;
    }

    println!("All workers shut down cleanly");
}

async fn flush_data(worker_id: usize) {
    tokio::time::sleep(Duration::from_millis(100)).await;
    println!("Worker {} flushed data", worker_id);
}

// Example 3: TaskTracker pattern
use tokio_util::task::TaskTracker;

#[tokio::main]
async fn main() {
    let tracker = TaskTracker::new();

    // Spawn tracked tasks
    for i in 0..10 {
        tracker.spawn(async move {
            tokio::time::sleep(Duration::from_secs(i)).await;
            println!("Task {} completed", i);
        });
    }

    // Close tracker (no new tasks)
    tracker.close();

    // Wait for all tasks
    tracker.wait().await;
    println!("All tasks completed");
}

// Example 4: Complete server with graceful shutdown
use tokio::net::TcpListener;
use tokio::sync::Notify;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;
    let shutdown = Arc::new(Notify::new());

    // Spawn signal handler
    let shutdown_clone = shutdown.clone();
    tokio::spawn(async move {
        signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");
        println!("Shutdown signal received");
        shutdown_clone.notify_waiters();
    });

    let tracker = TaskTracker::new();

    loop {
        tokio::select! {
            // Accept new connections
            result = listener.accept() => {
                let (socket, addr) = result?;
                println!("New connection from {}", addr);

                let shutdown = shutdown.clone();
                tracker.spawn(async move {
                    handle_connection(socket, shutdown).await;
                });
            }

            // Shutdown signal
            _ = shutdown.notified() => {
                println!("No longer accepting connections");
                break;
            }
        }
    }

    // Close tracker and wait for active connections
    tracker.close();
    println!("Waiting for {} active connections...", tracker.len());
    tracker.wait().await;

    println!("All connections closed. Goodbye!");
    Ok(())
}

use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

async fn handle_connection(mut socket: TcpStream, shutdown: Arc<Notify>) {
    let mut buf = [0; 1024];

    loop {
        tokio::select! {
            // Read from socket
            result = socket.read(&mut buf) => {
                match result {
                    Ok(0) => break, // Connection closed
                    Ok(n) => {
                        if socket.write_all(&buf[0..n]).await.is_err() {
                            break;
                        }
                    }
                    Err(_) => break,
                }
            }

            // Shutdown notification
            _ = shutdown.notified() => {
                println!("Connection closing due to shutdown");
                let _ = socket.write_all(b"Server shutting down\n").await;
                break;
            }
        }
    }
}
```

#### Shutdown Pattern Comparison

| Pattern | Complexity | Use Case | Cleanup Support |
|---------|-----------|----------|-----------------|
| `broadcast::channel` | Medium | Simple broadcast | ✅ Yes |
| `CancellationToken` | Low | Recommended default | ✅ Yes |
| `Notify` | Low | Single signal | ✅ Yes |
| `TaskTracker` | Medium | Wait for all tasks | ✅ Yes |

**Best Practices:**

1. **Always handle signals:**
```rust
tokio::select! {
    _ = signal::ctrl_c() => { /* shutdown */ }
    _ = signal::unix::signal(SignalKind::terminate()).unwrap().recv() => { /* shutdown */ }
}
```

2. **Use timeouts for cleanup:**
```rust
tokio::select! {
    _ = cleanup_task() => { /* finished */ }
    _ = tokio::time::sleep(Duration::from_secs(30)) => {
        eprintln!("Cleanup timeout, forcing shutdown");
    }
}
```

3. **Prefer CancellationToken** for most use cases (lightest weight, composable)

**When to Use:**
- Long-running servers
- Background workers
- Data processing pipelines
- Any application with cleanup requirements

**Common Pitfalls:**
```rust
// ❌ BAD: Doesn't wait for cleanup
token.cancel();
// Tasks still running!

// ✅ GOOD: Wait for tasks
token.cancel();
for handle in handles {
    handle.await?;
}
```

---

### 3.3 Channel Patterns

**Pattern Name:** Async Communication Primitives
**Complexity:** ⭐⭐⭐ Moderate
**Safety Guarantees:** Thread-safe message passing, no data races

#### Problem Solved
Enables safe communication between async tasks with different concurrency patterns (one-to-one, many-to-one, many-to-many).

#### Code Example

```rust
use tokio::sync::{mpsc, oneshot, broadcast};
use std::time::Duration;

// Example 1: MPSC (Multi-Producer, Single-Consumer)
#[tokio::main]
async fn main() {
    let (tx, mut rx) = mpsc::channel(32); // Buffer size 32

    // Spawn multiple producers
    for i in 0..5 {
        let tx = tx.clone();
        tokio::spawn(async move {
            for j in 0..3 {
                tx.send(format!("Message {} from worker {}", j, i))
                    .await
                    .unwrap();
                tokio::time::sleep(Duration::from_millis(100)).await;
            }
        });
    }

    // Drop original sender so receiver can complete
    drop(tx);

    // Single consumer
    while let Some(msg) = rx.recv().await {
        println!("Received: {}", msg);
    }
}

// Example 2: Oneshot (Request-Response Pattern)
#[tokio::main]
async fn main() {
    let (tx, rx) = oneshot::channel();

    // Spawn worker
    tokio::spawn(async move {
        let result = expensive_computation().await;
        let _ = tx.send(result); // Send result back
    });

    // Wait for result
    match rx.await {
        Ok(result) => println!("Got result: {}", result),
        Err(_) => println!("Worker died"),
    }
}

async fn expensive_computation() -> u64 {
    tokio::time::sleep(Duration::from_secs(1)).await;
    42
}

// Example 3: Broadcast (Multi-Producer, Multi-Consumer)
#[tokio::main]
async fn main() {
    let (tx, _rx) = broadcast::channel(16);

    // Spawn multiple consumers
    for i in 0..3 {
        let mut rx = tx.subscribe();
        tokio::spawn(async move {
            while let Ok(msg) = rx.recv().await {
                println!("Consumer {} received: {}", i, msg);
            }
        });
    }

    // Send messages (all consumers receive)
    for i in 0..5 {
        tx.send(format!("Broadcast {}", i)).unwrap();
        tokio::time::sleep(Duration::from_millis(100)).await;
    }
}

// Example 4: Command Pattern (mpsc + oneshot)
enum Command {
    Get { key: String, resp: oneshot::Sender<Option<String>> },
    Set { key: String, value: String, resp: oneshot::Sender<()> },
}

struct Cache {
    rx: mpsc::Receiver<Command>,
    data: std::collections::HashMap<String, String>,
}

impl Cache {
    fn new() -> (CacheHandle, Self) {
        let (tx, rx) = mpsc::channel(32);
        let cache = Cache {
            rx,
            data: std::collections::HashMap::new(),
        };
        (CacheHandle { tx }, cache)
    }

    async fn run(mut self) {
        while let Some(cmd) = self.rx.recv().await {
            match cmd {
                Command::Get { key, resp } => {
                    let value = self.data.get(&key).cloned();
                    let _ = resp.send(value);
                }
                Command::Set { key, value, resp } => {
                    self.data.insert(key, value);
                    let _ = resp.send(());
                }
            }
        }
    }
}

#[derive(Clone)]
struct CacheHandle {
    tx: mpsc::Sender<Command>,
}

impl CacheHandle {
    

…(truncated)
