๐Ÿฆ€ Functional Rust
๐ŸŽฌ Pattern Matching Exhaustive match, destructuring, guards, let-else โ€” compiler-verified branching.
๐Ÿ“ Text version (for readers / accessibility)

โ€ข match is exhaustive โ€” the compiler ensures every variant is handled

โ€ข Destructuring extracts fields from structs, tuples, and enums in one step

โ€ข Guards (if conditions) add extra logic to match arms

โ€ข if let and let-else provide concise single-pattern matching

โ€ข Nested patterns and @ bindings handle complex data shapes elegantly

576: `matches!` Macro

Difficulty: 2 Level: Beginner Test a value against a pattern and get a `bool` โ€” without a full `match` expression.

The Problem This Solves

You often need to answer a simple yes/no question: "is this value `Status::Active`?" or "is this `Ok` with a positive number?" Without `matches!`, the answer requires a full `match` or an `if let` block โ€” several lines for what should be a one-liner. In iterator `filter` chains, this is especially awkward. `matches!(value, pattern)` collapses this to a boolean expression. It works with any pattern Rust supports: enum variants, OR patterns (`A | B`), guards (`if condition`), and nested destructuring. It's purely syntactic โ€” the compiler expands it to a match with `true` and `false` arms. There's no runtime overhead.

The Intuition

`matches!(x, Pattern)` is exactly `if let Pattern = x { true } else { false }`, but readable at a glance. It slots into any boolean context: `filter`, `assert!`, `if` conditions, `while` conditions. OR patterns (`matches!(x, A | B | C)`) test multiple variants in one expression โ€” the boolean equivalent of consolidating match arms.

How It Works in Rust

1. Basic use โ€” `matches!(status, Status::Active)` returns `true` or `false`. 2. In `filter` โ€” `.filter(|u| matches!(u, Status::Active | Status::Pending))` โ€” concise, no closure body needed. 3. With guards โ€” `matches!(n, x if x % 2 == 0 && x <= 6)` โ€” the guard runs after the pattern matches. 4. With enum data โ€” `matches!(s, Shape::Circle(_))` โ€” the `_` wildcard matches any wrapped value. 5. In `assert!` โ€” `assert!(matches!(r, Ok(n) if n > 0))` โ€” readable assertions in tests.

What This Unlocks

Key Differences

ConceptOCamlRust
Pattern as booleanNo direct equivalent; use `match ... -> bool``matches!(value, pattern)` macro โ€” expands to `match`
OR patterns in boolean`match x with A \B -> true \_ -> false``matches!(x, A \B)` โ€” same semantics, much shorter
Guards in boolean test`match x with p when cond -> true \_ -> false``matches!(x, p if cond)`
In filter predicates`List.filter (function A -> true \_ -> false)``.filter(\x\matches!(x, A))`
#[derive(Debug)]
enum Status { Active, Inactive, Pending, Banned }

fn main() {
    let users = [Status::Active, Status::Inactive, Status::Pending, Status::Banned, Status::Active];

    let active = users.iter().filter(|u| matches!(u, Status::Active)).count();
    let usable = users.iter().filter(|u| matches!(u, Status::Active | Status::Pending)).count();
    println!("active={} usable={}", active, usable);

    // matches! with guard
    let nums = vec![1,2,3,4,5,6,7,8,9,10];
    let even_small: Vec<_> = nums.iter().copied()
        .filter(|&n| matches!(n, x if x%2==0 && x<=6))
        .collect();
    println!("even โ‰ค 6: {:?}", even_small);

    // in assert!
    let r: Result<i32,&str> = Ok(42);
    assert!(matches!(r, Ok(n) if n > 0));

    // with enum data
    #[derive(Debug)]
    enum Shape { Circle(f64), Square(f64), Other }
    let shapes = vec![Shape::Circle(1.0), Shape::Square(2.0), Shape::Other, Shape::Circle(0.5)];
    let circles = shapes.iter().filter(|s| matches!(s, Shape::Circle(_))).count();
    let large   = shapes.iter().filter(|s| matches!(s, Shape::Circle(r)|Shape::Square(r) if *r>1.0)).count();
    println!("circles={} large={}", circles, large);

    let words = ["fn","let","hello","match","world"];
    let kw: Vec<_> = words.iter().filter(|&&w| matches!(w,"fn"|"let"|"match"|"if")).collect();
    println!("keywords: {:?}", kw);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test] fn is_active() { assert!( matches!(Status::Active,  Status::Active)); }
    #[test] fn not_active(){ assert!(!matches!(Status::Banned, Status::Active)); }
    #[test] fn guard()     { assert!( matches!(4, x if x%2==0)); }
}
(* OCaml: pattern-to-bool *)
type status = Active | Inactive | Pending | Banned

let is_active  = function Active -> true | _ -> false
let is_usable  = function Active | Pending -> true | _ -> false

let () =
  let users = [Active;Inactive;Pending;Banned;Active] in
  Printf.printf "active=%d usable=%d\n"
    (List.length (List.filter is_active  users))
    (List.length (List.filter is_usable  users));
  let s = "abc123" in
  let n = String.to_seq s |> Seq.filter (fun c -> c>='0' && c<='9') |> Seq.fold_left (fun a _ -> a+1) 0 in
  Printf.printf "digits in '%s': %d\n" s n