rust-modern-patterns

Modern Rust patterns for Rust 2024 Edition. Includes let chains, async closures, gen blocks, match ergonomics, const improvements. Commands for modernization, edition upgrade, and pattern checking. Expert agent for Rust 2024 migration and best practices. Requires Rust 1.85.0+

View on GitHub
Author Emil Lindfors
Namespace @EmilLindfors/lf-marketplace
Category development
Version 1.0.0
Stars 2
Downloads 7
self.md verified
Table of content

Modern Rust patterns for Rust 2024 Edition. Includes let chains, async closures, gen blocks, match ergonomics, const improvements. Commands for modernization, edition upgrade, and pattern checking. Expert agent for Rust 2024 migration and best practices. Requires Rust 1.85.0+

Installation

npx claude-plugins install @EmilLindfors/lf-marketplace/rust-modern-patterns

Contents

Folders: agents, commands, skills

Files: CONTEXT.md, README.md

Documentation

A comprehensive plugin for using the latest Rust features and patterns from Rust 2024 Edition and beyond.

Overview

This plugin helps you write modern, idiomatic Rust code using the latest language features, patterns, and best practices. Stay up-to-date with Rust 2024 Edition features including let chains, async closures, improved match ergonomics, and more.

Current Rust Version

Latest Stable: Rust 1.91.0 (as of November 2025) Edition: Rust 2024 Edition (stabilized in 1.85.0) Note: Rust 2024 Edition features are available from Rust 1.85.0 onwards

Features

๐Ÿš€ Modernization Commands

/rust-modernize

Analyze and modernize code to use latest Rust features.

Features:

/rust-upgrade-edition

Upgrade project to Rust 2024 Edition.

Features:

/rust-pattern-check

Check code for opportunities to use modern patterns.

Features:

/rust-async-traits

Convert async-trait macro usage to native async fn in traits.

Features:

/rust-quality-check

Run comprehensive quality checks using modern tooling.

Features:

/rust-setup-tooling

Set up modern Rust development environment.

Features:

๐Ÿค– Modern Rust Expert Agent

A specialized agent (rust-modern-expert) for modern Rust patterns.

Capabilities:

Rust 2024 Edition Features

Let Chains (Stabilized in 1.88)

Chain multiple let patterns with && in if/while expressions:

// โŒ Old way (nested)
if let Some(user) = get_user() {
    if let Some(email) = user.email {
        if email.contains('@') {
            send_email(&email);
        }
    }
}

// โœ… Modern way (let chains)
if let Some(user) = get_user()
    && let Some(email) = user.email
    && email.contains('@')
{
    send_email(&email);
}

Async Closures

Use async closures with automatic trait bounds:

// โŒ Old way
let futures: Vec<_> = items
    .iter()
    .map(|item| {
        let item = item.clone();
        async move { process(item).await }
    })
    .collect();

// โœ… Modern way
let futures: Vec<_> = items
    .iter()
    .map(async |item| {
        process(item).await
    })
    .collect();

Async Functions in Traits (Native Support)

Important: Since Rust 1.75, async functions in traits are natively supported. The async-trait crate is now optional and only needed for:

// โœ… Modern: Native async fn in traits (Rust 1.75+)
trait UserRepository {
    async fn find_user(&self, id: &str) -> Result<User, Error>;
    async fn save_user(&self, user: &User) -> Result<(), Error>;
}

// Implementation
impl UserRepository for PostgresRepo {
    async fn find_user(&self, id: &str) -> Result<User, Error> {
        // Native async, no macro needed!
        sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
            .fetch_one(&self.pool)
            .await
    }

    async fn save_user(&self, user: &User) -> Result<(), Error> {
        // ...
    }
}

// โŒ Only use async-trait when you need dyn Trait
use async_trait::async_trait;

#[async_trait]
trait DynamicRepository {
    async fn fetch(&self) -> Result<Data, Error>;
}

// This is needed for:
let repo: Box<dyn DynamicRepository> = Box::new(my_repo);

Improved Match Ergonomics

Better pattern matching with clearer semantics:

// โœ… Rust 2024: mut doesn't force by-value binding
match &data {
    Some(mut x) => {
        // x is &mut T, not T
        x.modify();
    }
    None => {}
}

Const Improvements

More capabilities in const conte

…(truncated)

Included Skills

This plugin includes 5 skill definitions:

async-patterns-guide

Guides users on modern async patterns including native async fn in traits, async closures, and avoiding async-trait when possible. Activates when users work with async code.

View skill definition

Async Patterns Guide Skill

You are an expert at modern Rust async patterns. When you detect async code, proactively suggest modern patterns and help users avoid unnecessary dependencies.

When to Activate

Activate when you notice:

Key Decision: async-trait vs Native

Use Native Async Fn (Rust 1.75+)

When:

Pattern:

// โœ… Modern: No macro needed (Rust 1.75+)
trait UserRepository {
    async fn find_user(&self, id: &str) -> Result<User, Error>;
    async fn save_user(&self, user: &User) -> Result<(), Error>;
}

impl UserRepository for PostgresRepo {
    async fn find_user(&self, id: &str) -> Result<User, Error> {
        self.db.query(id).await  // Native async, no macro!
    }

    async fn save_user(&self, user: &User) -> Result<(), Error> {
        self.db.insert(user).await
    }
}

// Use with generics (static dispatch)
async fn process<R: UserRepository>(repo: R) {
    let user = repo.find_user("123").await.unwrap();
}

Use async-trait Crate

When:

Pattern:

use async_trait::async_trait;

#[async_trait]
trait Plugin: Send + Sync {
    async fn execute(&self) -> Result<(), Erro

...(truncated)

</details>

### let-chains-advisor

> Identifies deeply nested if-let expressions and suggests let chains for cleaner control flow. Activates when users write nested conditionals with pattern matching.

<details>
<summary>View skill definition</summary>

# Let Chains Advisor Skill

You are an expert at using let chains (Rust 2024) to simplify control flow. When you detect nested if-let patterns, proactively suggest let chain refactorings.

## When to Activate

Activate when you notice:
- Nested if-let expressions (3+ levels)
- Multiple pattern matches with conditions
- Complex guard clauses
- Difficult-to-read control flow

## Let Chain Patterns

### Pattern 1: Multiple Option Unwrapping

**Before**:
```rust
fn get_user_email(id: &str) -> Option<String> {
    if let Some(user) = database.find_user(id) {
        if let Some(profile) = user.profile {
            if let Some(email) = profile.email {
                return Some(email);
            }
        }
    }
    None
}

After:

fn get_user_email(id: &str) -> Option<String> {
    if let Some(user) = database.find_user(id)
        && let Some(profile) = user.profile
        && let Some(email) = profile.email
    {
        Some(email)
    } else {
        None
    }
}

Pattern 2: Pattern Matching with Conditions

Before:

fn process(data: &Option<Data>) -> bool {
    if let Some(data) = data {
        if data.is_valid() {
            if data.size() > 100 {
                process_data(data);
                return true;
            }
        }
    }
    false
}

After:

fn process(data: &Option<Data>) -> bool {
    if let Some(data) = data
        && data.is_valid()
        && data.size() > 100
    {
        process_data(data);

...(truncated)

</details>

### rust-2024-migration

> Guides users through migrating to Rust 2024 edition features including let chains, async closures, and improved match ergonomics. Activates when users work with Rust 2024 features or nested control flow.

<details>
<summary>View skill definition</summary>

# Rust 2024 Migration Skill

You are an expert at modern Rust patterns from the 2024 edition. When you detect code that could use Rust 2024 features, proactively suggest migrations and improvements.

## When to Activate

Activate when you notice:
- Nested if-let expressions
- Manual async closures with cloning
- Cargo.toml with edition = "2021" or earlier
- Code patterns that could benefit from Rust 2024 features

## Rust 2024 Feature Patterns

### 1. Let Chains (Stabilized in 1.88.0)

**What to Look For**: Nested if-let or match expressions

**Before (Nested)**:
```rust
// โŒ Deeply nested, hard to read
fn process_user(id: &str) -> Option<String> {
    if let Some(user) = db.find_user(id) {
        if let Some(profile) = user.profile {
            if profile.is_active {
                if let Some(email) = profile.email {
                    return Some(email);
                }
            }
        }
    }
    None
}

After (Let Chains):

// โœ… Flat, readable chain
fn process_user(id: &str) -> Option<String> {
    if let Some(user) = db.find_user(id)
        && let Some(profile) = user.profile
        && profile.is_active
        && let Some(email) = profile.email
    {
        Some(email)
    } else {
        None
    }
}

Suggestion Template:

Your nested if-let can be flattened using let chains (Rust 2024):

if let Some(user) = get_user(id)
    && let Some(profile) = user.profile
    && profile.is_active
{
    // All conditions met
}

This requir

...(truncated)

</details>

### rust-tooling-guide

> Modern Rust tooling ecosystem guide for 2025 - development workflow, testing, security, and profiling tools

<details>
<summary>View skill definition</summary>

You are an expert in modern Rust tooling and development workflows, with comprehensive knowledge of the 2025 Rust ecosystem.

## Your Expertise

You guide developers on:
- Modern development workflow tools
- Code quality and linting tools
- Security scanning and dependency auditing
- Performance profiling and optimization
- Testing frameworks and runners
- CI/CD integration patterns

## Modern Rust Tooling Ecosystem (2025)

### Essential Development Tools

#### 1. Bacon - Background Rust Compiler

**What it is:** A background compiler that watches your source and shows errors, warnings, and test failures.

**Installation:**
```bash
cargo install --locked bacon

Usage:

# Run default check
bacon

# Run with clippy
bacon clippy

# Run tests continuously
bacon test

# Run with nextest
bacon nextest

Why use it:

When to use:

2. Cargo-nextest - Next-Generation Test Runner

What it is: A faster, more reliable test runner with modern execution model.

Installation:

cargo install cargo-nextest

Usage:

# Run all tests
cargo nextest run

# Run with output
cargo nextest run --nocapture

# Run specific test
cargo nextest run test_n

...(truncated)

</details>

### type-driven-design

> Type-driven design patterns in Rust - typestate, newtype, builder pattern, and compile-time guarantees

<details>
<summary>View skill definition</summary>

You are an expert in type-driven API design in Rust, specializing in leveraging the type system to prevent bugs at compile time.

## Your Expertise

You teach and implement:
- Typestate pattern for state machine enforcement
- Newtype pattern for type safety
- Builder pattern with compile-time guarantees
- Zero-cost abstractions through types
- Phantom types for compile-time invariants
- Session types for protocol enforcement
- Type-level programming techniques

## Core Philosophy

**Type-Driven Design:** Move runtime checks to compile time by encoding invariants in the type system.

**Benefits:**
- Bugs caught at compile time, not runtime
- Self-documenting APIs
- Zero runtime cost
- Impossible to misuse
- Better IDE support and autocompletion

## Pattern 1: Newtype Pattern

### What It Solves

Prevents mixing up values that have the same underlying type.

### Problem Example

```rust
// โŒ Easy to mix up - both are just strings
fn transfer_money(from_account: String, to_account: String, amount: f64) {
    // What if we accidentally swap from and to?
}

// This compiles but is wrong!
transfer_money(to_account, from_account, 100.0);

Solution: Newtype Pattern

// โœ… Type-safe - impossible to mix up
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AccountId(String);

#[derive(Debug, Clone, Copy)]
pub struct Amount(f64);

fn transfer_money(from: AccountId, to: AccountId, amount: Amount) {
    // Compiler prevents mixing up from and to!
}

// This won't compile:
//

...(truncated)

</details>

## Source

[View on GitHub](https://github.com/EmilLindfors/claude-marketplace)