Files
gh-emillindfors-claude-mark…/skills/let-chains-advisor/SKILL.md
2025-11-29 18:25:55 +08:00

3.2 KiB

name, description, allowed-tools, version
name description allowed-tools version
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. Read, Grep 1.0.0

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:

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);
        true
    } else {
        false
    }
}

Pattern 3: Multiple Result Checks

Before:

fn load_config() -> Result<Config, Error> {
    if let Ok(path) = get_config_path() {
        if let Ok(content) = std::fs::read_to_string(path) {
            if let Ok(config) = toml::from_str(&content) {
                return Ok(config);
            }
        }
    }
    Err(Error::ConfigNotFound)
}

After:

fn load_config() -> Result<Config, Error> {
    if let Ok(path) = get_config_path()
        && let Ok(content) = std::fs::read_to_string(path)
        && let Ok(config) = toml::from_str(&content)
    {
        Ok(config)
    } else {
        Err(Error::ConfigNotFound)
    }
}

Pattern 4: While Loops

Before:

while let Some(item) = iterator.next() {
    if item.is_valid() {
        if let Ok(processed) = process_item(item) {
            results.push(processed);
        }
    }
}

After:

while let Some(item) = iterator.next()
    && item.is_valid()
    && let Ok(processed) = process_item(item)
{
    results.push(processed);
}

Requirements

  • Rust Version: 1.88+
  • Edition: 2024
  • Cargo.toml:
[package]
edition = "2024"
rust-version = "1.88"

Your Approach

When you see nested patterns:

  1. Count nesting levels (3+ suggests let chains)
  2. Check if all branches return/continue
  3. Suggest let chain refactoring
  4. Verify Rust version compatibility

Proactively suggest let chains for cleaner, more readable code.