macro_rules! let_extract {
($($p:ident)::+ ( $($i:ident),* $(,)* ) , $t:expr, match { $($body:tt)* }) => { ... };
($($p:ident)::+ { $($i:ident),* $(,)* } , $t:expr, match { $($body:tt)* }) => { ... };
($($p:ident)::+ { $($k:ident : $v:ident),* $(,)* } , $t:expr, match { $($body:tt)* }) => { ... };
($($p:ident)::+ ( $($its:tt)* ) , $t:expr, $els:expr) => { ... };
($($p:ident)::+ { $($its:tt)* } , $t:expr, $els:expr) => { ... };
}
Expand description
Extract the fields of a single variant from an enum, binding them into the current scope.
If the binding fails due to the variant being incorrect, execute the error
expression. Alternatively, a partial match
block may be written to handle
the remaining cases.
§Examples
Given the following enum:
ⓘ
enum Foo {
A(i32),
B(i32, i32),
C { x: i32, y: i32 },
D { z: i32 },
}
If the extract succeeds, the variable names written bind into the current scope.
let a = Foo::A(10);
let_extract!(Foo::A(x), a, panic!());
assert_eq!(x, 10);
If it fails, the expression passed in as the 3rd argument is executed instead, and can cause execution to diverge.
let a = Foo::A(10);
let_extract!(Foo::B(x, y), a, return);
unreachable!();
Alternatively, it can provide default values for the variable bindings, from left to right.
let a = Foo::A(10);
let_extract!(Foo::B(x, y), a, (40, 50));
assert_eq!(x, 40);
assert_eq!(y, 50);
The other cases can each be handled specifically with a match-like block.
let a = Foo::A(10);
let_extract!(Foo::B(x, y), a, match {
Foo::A(x) => return,
Foo::C{..} => unreachable!(),
Foo::D{..} => unreachable!(),
});
unreachable!();
Struct variants are also supported, and can be written either as { field }
or { field: binding }
.
let d = Foo::D { z: 10 };
let_extract!(Foo::D{ z }, d, unreachable!());
assert_eq!(z, 10);
let_extract!(Foo::D{ z: apples }, d, unreachable!());
assert_eq!(apples, 10);