#![doc = include_str!("../README.md")]
#[macro_export]
macro_rules! iunpack {
(@if($($t:tt)*) else $($f:tt)*) => ($($t)*);
(@if else $($f:tt)*) => ($($f)*);
{@revpat_do_iter_back($iter:ident, $body:block, $errbody:expr)
$(($used:pat) $(($pat:pat))*)?
} => {
$crate::iunpack!(@if$((
$crate::iunpack!(
@revpat_do_iter_back($iter, {
if let ::core::option::Option::Some($used)
= ::core::iter::DoubleEndedIterator::next_back(&mut $iter)
{
$body
} else {
$errbody
}
}, $errbody) $(($pat))*
)
))? else $body)
};
{@sized_pat($iter:ident, $body:block, $errbody:block, $errval:ident)
$($fpat:pat $(, $pat:pat)*)?
} => {
$crate::iunpack!(@if$((
if let ::core::option::Option::Some($fpat)
= ::core::iter::Iterator::next(&mut $iter) {
$errval += 1;
$crate::iunpack!(@sized_pat(
$iter,
$body,
$errbody,
$errval
) $($pat),*)
} else $errbody
))? else $body)
};
{@sized_pat($iter:ident, $body:block, $errbody:block)
$($fpat:pat $(, $pat:pat)*)?
} => {
$crate::iunpack!(@if$((
if let ::core::option::Option::Some($fpat)
= ::core::iter::Iterator::next(&mut $iter) {
$crate::iunpack!(@sized_pat(
$iter,
$body,
$errbody
) $($pat),*)
} else $errbody
))? else $body)
};
{
$($pat:pat),* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => {{
let mut __iter = ::core::iter::IntoIterator::into_iter($iter);
$crate::iunpack!(@sized_pat(__iter, {
if let ::core::option::Option::Some(_)
= ::core::iter::Iterator::next(&mut __iter) {
$errbody
} else {
$body
}
}, { $errbody }) $($pat),*)
}};
{
$($pat:pat),* $(,)?
= $iter:expr => $body:block
else($err:ident) $errbody:block
} => {{
let mut __iter = ::core::iter::IntoIterator::into_iter($iter);
let mut $err = 0usize;
$crate::iunpack!(@sized_pat(__iter, {
if let ::core::option::Option::Some(_)
= ::core::iter::Iterator::next(&mut __iter) {
$errbody
} else {
$body
}
}, { $errbody }, $err) $($pat),*)
}};
{
$($fpat:pat ,)* * $($mid:ident $(: $ty:ty)?)? $(, $bpat:pat)* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => {{
let mut __iter = ::core::iter::IntoIterator::into_iter($iter);
$crate::iunpack!(@sized_pat(__iter, {
$crate::iunpack!(
@revpat_do_iter_back(__iter, {
$(
let $mid = <$crate::iunpack!(
@if$(($ty))?else ::std::vec::Vec<_>)
as ::core::iter::FromIterator<_>>
::from_iter(__iter);
)?
$body
}, $errbody)
$(($bpat))*
)
}, { $errbody }) $($fpat),*)
}};
{
$($fpat:pat ,)* *=$mid:ident $(, $bpat:pat)* $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => {{
let mut $mid = ::core::iter::IntoIterator::into_iter($iter);
$crate::iunpack!(@sized_pat($mid, {
$crate::iunpack!(
@revpat_do_iter_back($mid, {
$body
}, $errbody)
$(($bpat))*
)
}, { $errbody }) $($fpat),*)
}};
{
$($fpat:pat ,)* ** $(, $bpat:pat)+ $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => {loop {
let mut __iter = ::core::iter::IntoIterator::into_iter($iter);
break $crate::iunpack!(@sized_pat(__iter, {
let mut __buf = [$(
match ::core::iter::Iterator::next(&mut __iter) {
::core::option::Option::Some(
$crate::iunpack!(@if(x) else $bpat)
) => x,
::core::option::Option::None => break $errbody,
}
),+];
let mut __i = 0;
while let ::core::option::Option::Some(__elem)
= ::core::iter::Iterator::next(&mut __iter) {
__buf[__i] = __elem;
__i += 1;
__i %= __buf.len();
}
__buf.rotate_left(__i);
#[allow(irrefutable_let_patterns)]
if let [$($bpat),+] = __buf {
$body
} else { $errbody }
}, { $errbody }) $($fpat),*)
}};
{
$($fpat:pat ,)* ** $mid:ident $(: $ty:ty)? $(, $bpat:pat)+ $(,)?
= $iter:expr => $body:block
else $errbody:expr
} => {loop {
let mut __iter = ::core::iter::IntoIterator::into_iter($iter);
break $crate::iunpack!(@sized_pat(__iter, {
let mut __buf = [$(
match ::core::iter::Iterator::next(&mut __iter) {
::core::option::Option::Some(
$crate::iunpack!(@if(x) else $bpat)
) => x,
::core::option::Option::None => break $errbody,
}
),+];
let mut __i = 0;
let mut $mid = <$crate::iunpack!(@if$(($ty))?
else ::std::vec::Vec<_>)
as ::core::default::Default>::default();
while let ::core::option::Option::Some(__elem)
= ::core::iter::Iterator::next(&mut __iter) {
::core::iter::Extend::extend(
&mut $mid,
::core::option::Option::Some(
::core::mem::replace(&mut __buf[__i], __elem)
)
);
__i += 1;
__i %= __buf.len();
}
__buf.rotate_left(__i);
#[allow(irrefutable_let_patterns)]
if let [$($bpat),+] = __buf {
$body
} else { $errbody }
}, { $errbody }) $($fpat),*)
}};
}