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 ──┤│