macro_rules! iunpack {
(@if($($t:tt)*) else $($f:tt)*) => { ... };
(@if else $($f:tt)*) => { ... };
{@revpat_do_iter_back($iter:ident, $body:block, $errbody:expr)
$(($used:pat) $(($pat:pat))*)?
} => { ... };
{@sized_pat($iter:ident, $body:block, $errbody:block, $errval:ident)
$($fpat:pat $(, $pat:pat)*)?
} => { ... };
{@sized_pat($iter:ident, $body:block, $errbody:block)
$($fpat:pat $(, $pat:pat)*)?
} => { ... };
{
$($pat:pat),* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => { ... };
{
$($pat:pat),* $(,)?
= $iter:expr => $body:block
else($err:ident) $errbody:block
} => { ... };
{
$($fpat:pat ,)* * $($mid:ident $(: $ty:ty)?)? $(, $bpat:pat)* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => { ... };
{
$($fpat:pat ,)* *=$mid:ident $(, $bpat:pat)* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => { ... };
{
$($fpat:pat ,)* ** $(, $bpat:pat)+ $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => { ... };
{
$($fpat:pat ,)* ** $mid:ident $(: $ty:ty)? $(, $bpat:pat)+ $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => { ... };
}
Expand description
Use pattern unpack iterator
The expression after the equal sign must implement IntoIterator
.
The final pattern may be followed by a trailing comma.
Use else to handle iterator length mismatch or pattern mismatch
- Use
*name
pattern any elements toVec
, useDoubleEndedIterator
pattern end elements. - Use
*name: Type
pattern any elements collect into implFromIterator
. - Use
*=iter
pattern start and end elements, do not check iter is stopped. Internally use the given variable name to store iterator for future use. - Use
**name
like*name
, but useIterator
There may be an internal loop, please use the label to break or continue.
ยงExamples
Sized iterator
assert_eq!(iunpack!(a, b, c, d, e = 0..5 => {
(a, b, c, d, e)
} else panic!()), (0, 1, 2, 3, 4));
assert_eq!(iunpack!(a, b, c, d, e = 0..3 => {
panic!()
} else(err) {
err
}), 3); // fail, not enough values
assert_eq!(iunpack!(a, b, c, d, e = 0..7 => {
panic!()
} else(err) {
err
}), 5); // fail, too many values
Any size iterator
assert_eq!(iunpack!(a, b, *c, d, e = 0..8 => {
(a, b, c, d, e)
} else panic!()), (0, 1, vec![2, 3, 4, 5], 6, 7));
assert_eq!(iunpack!(a, b, *=c, d, e = 0..8 => {
(a, b, c.collect::<Vec<_>>(), d, e)
} else panic!()), (0, 1, vec![2, 3, 4, 5], 6, 7));
assert_eq!(iunpack!(a, b, *c: HashSet<_>, d, e = 0..8 => {
(a, b, c, d, e)
} else panic!()), (0, 1, HashSet::from([2, 3, 4, 5]), 6, 7));
// use Iterator, is not DoubleEndedIterator
assert_eq!(iunpack!(a, b, **c, d, e = 0..8 => {
(a, b, c, d, e)
} else panic!()), (0, 1, vec![2, 3, 4, 5], 6, 7));
// no collect
assert_eq!(iunpack!(a, b, *, d, e = 0..8 => {
(a, b, d, e)
} else panic!()), (0, 1, 6, 7));
// use Iterator, is not DoubleEndedIterator, no collect
assert_eq!(iunpack!(a, b, **, d, e = 0..8 => {
(a, b, d, e)
} else panic!()), (0, 1, 6, 7));
Pattern example
assert_eq!(iunpack!(_a, _b, 2..=10 = 0..3 => { true } else panic!()), true);
assert_eq!(iunpack!((0 | 1 | 2), _b, _c = 0..3 => {
true
} else panic!()), true);
assert_eq!(iunpack!(*, 2..=10 = 0..3 => {
true
} else panic!()), true);
assert_eq!(iunpack!((0 | 1 | 2), * = 0..3 => {
true
} else panic!()), true);
// fails
assert_eq!(iunpack!(_a, _b, 3..=10 = 0..3 => {
panic!()
} else true), true);
assert_eq!(iunpack!((1 | 2), _b, _c = 0..3 => {
panic!()
} else true), true);
assert_eq!(iunpack!(_a, **, 3..=10 = 0..3 => {
panic!()
} else true), true);
assert_eq!(iunpack!((1 | 2), * = 0..3 => {
panic!()
} else true), true);