Macro kiam::when

source · []
macro_rules! when {
    (
        $(
            $(let $pat:pat = )? $cond:expr => $branch:expr
        ),+
        $(, _ => $def_branch:expr)?
        $(,)?
    ) => { ... };
}
Expand description

Better syntax for if/else if/else similar to match syntax

Usage

Usage is similar to the usage of match, but instead of patterns, branches are guarded by boolean expression:

kiam::when! {
    false => (),
    true => (),
    // ...
}

_ can be used as a default branch (it’s also required to use when! in expression position):

let x = kiam::when! {
    false => 0,
    _ => 1,
};

assert_eq!(x, 1);

You can also use let <pat> = to match a pattern, but in difference with match you’ll have to provide an expression for every pattern:

let a = None;
let b = Some(17);
let fallible = || Err(());

let x = kiam::when! {
    let Some(x) = a => x,
    let Ok(x) = fallible() => x,
    let Some(x) = b => (x as u32) + 1,
    _ => 1,
};

assert_eq!(x, 18);

Last notes:

  • You can also compare structure literals without brackets (you can’t do this with if/else if/else chain)
  • You can mixup boolean-branches with pattern matching
  • Only one branch is executed (not to be confused with switch in C-like languages)
let mut x = 0;

kiam::when! {
    let Ok(_) = Err::<(), _>(()) => x = 1,
    true => x = 2,
    true => x = 3,
    let Some(n) = Some(42) => x = n,
};

assert_eq!(x, 2);
#[derive(PartialEq)]
struct Struct { a: i32 }

// This does not compile because of the ambiguity
if Struct { a: 0 } == Struct { a: 0 } {
    // ...
}
#[derive(PartialEq)]
struct Struct { a: i32 }

kiam::when! {
    // This, on the other hand, compiles fine
    Struct { a: 0 } == Struct { a: 0 } => {
        // ...
    },
}

Grammar

grammar:
                  ╭───────────────>────────────────╮  ╭────>────╮
                  │                                │  │         │
│├──╭── line ──╮──╯── "," ── "_" ── "=>" ── expr ──╰──╯── "," ──╰──┤│
    │          │
    ╰── "," ───╯

line:
    ╭─────────────>─────────────╮
    │                           │
│├──╯── "let"/i ── pat ── "=" ──╰── expr ── "=>" ── expr ──┤│