#[macro_export]
macro_rules! stack_pinned {
(
$var:ident
) => (
let (ref $var,) = ($var,);
let $var = unsafe {
extern {}
$crate::core::pin::Pin::new_unchecked($var)
};
);
(
mut $var:ident
) => (
let (ref mut $var,) = ($var,);
#[allow(unused_mut)]
let mut $var = unsafe {
extern {}
$crate::core::pin::Pin::new_unchecked($var)
};
);
}
#[macro_export]
macro_rules! mk_gen {
(@input
let [$($mut:tt)?] $var:ident =
box $generator:tt ( $($args:expr),* $(,)? )
$(;)?
) => (
let generator = $generator;
let var = $crate::GeneratorFn::empty();
let mut $var = ::std::boxed::Box::pin(var);
$var .as_mut()
.init(
generator,
($($args, )*),
)
;
);
(@input
let [$($mut:tt)?] $var:ident =
$generator:tt ( $($args:expr),* $(,)? )
$(;)?
) => (
let var = $crate::GeneratorFn::empty();
$crate::stack_pinned!(mut var);
var .as_mut()
.init(
$generator,
($($args, )*),
)
;
let $($mut)? $var = var;
);
(
let mut $($tt:tt)*
) => (
$crate::mk_gen!(@input let [mut] $($tt)*)
);
(
let $($tt:tt)*
) => (
$crate::mk_gen!(@input let [] $($tt)*)
);
}
#[macro_export]
macro_rules! gen_iter {
(
for $pat:pat in $generator:tt ($($args:expr),* $(,)?) $block:block
) => ({
$crate::mk_gen!(let generator = $generator ($($args),*));
$crate::gen_iter!(
for $pat in generator $block
)
});
(
for $pat:pat in $generator:tt $block:block
) => (match $generator { mut generator => {
use $crate::{
core::pin::Pin,
Generator,
GeneratorState,
};
let mut resume_generator = || -> GeneratorState<_, _> {
Generator::resume(
Pin::as_mut(&mut generator)
)
};
loop {
match resume_generator() {
| GeneratorState::Yield($pat) => $block,
| GeneratorState::Return(ret) => break ret,
}
}
}});
}