[−][src]Struct next_gen::GeneratorFn
An instance of a #[generator]
-tagged function.
These are created in a two-step fashion:
-
First, an
empty()
generator is created, which is to be pinned. -
Once it is pinned, it can be
.init()
-ialized with a#[generator]
-tagged function.
As with any Generator
, for a GeneratorFn
to be usable, it must have
been previously Pin
ned:
-
either in the heap, through
Box::pin
;use ::next_gen::{prelude::*, GeneratorFn, GeneratorState}; #[generator(u32)] fn countdown (mut remaining: u32) { while let Some(next) = remaining.checked_sub(1) { yield_!(remaining); remaining = next; } } let generator = GeneratorFn::empty(); let mut generator = Box::pin(generator); generator.as_mut().init(countdown, (3,)); let mut next = || generator.as_mut().resume(); assert_eq!(next(), GeneratorState::Yield(3)); assert_eq!(next(), GeneratorState::Yield(2)); assert_eq!(next(), GeneratorState::Yield(1)); assert_eq!(next(), GeneratorState::Return(()));
-
or in the stack, through
stack_pinned!
.use ::next_gen::{prelude::*, GeneratorFn, GeneratorState}; #[generator(u32)] fn countdown (mut remaining: u32) { while let Some(next) = remaining.checked_sub(1) { yield_!(remaining); remaining = next; } } let generator = GeneratorFn::empty(); stack_pinned!(mut generator); generator.as_mut().init(countdown, (3,)); let mut next = || generator.as_mut().resume(); assert_eq!(next(), GeneratorState::Yield(3)); assert_eq!(next(), GeneratorState::Yield(2)); assert_eq!(next(), GeneratorState::Yield(1)); assert_eq!(next(), GeneratorState::Return(()));
mk_gen!
mk_gen!
is a macro that reduces the boilerplate of the above
patterns, by performing the two step-initialization within a single macro
call.
Stack vs. heap
Since stack-pinning prevents ever moving the generator around (duh), once
stack-pinned, a Generator
cannot be, for instance, returned. For that,
Pin
ning in the heap is necessary:
use ::next_gen::prelude::*; pub fn countdown (count: u32) -> impl Iterator<Item = u32> + 'static { #[generator(u32)] fn countdown (mut remaining: u32) { while let Some(next) = remaining.checked_sub(1) { yield_!(remaining); remaining = next; } } mk_gen!(let generator = box countdown(count)); generator.into_iter() // A pinned generator is iterable. }
However, pinning in the stack is vastly more performant (it is zero-cost in
release mode), and suffices for local iteration. It is thus the blessed
form of Pin
ning, which should be favored over box
-ing.
use ::next_gen::prelude::*; #[generator(u32)] fn countdown (mut remaining: u32) { while let Some(next) = remaining.checked_sub(1) { yield_!(remaining); remaining = next; } } mk_gen!(let generator = countdown(3)); assert_eq!( generator.into_iter().collect::<Vec<_>>(), [3, 2, 1], );
Methods
impl<Item, F: Future> GeneratorFn<Item, F>
[src]
pub fn empty() -> Self
[src]
Reserves memory for an empty generator.
pub fn init<'pin, 'yield_slot, Args>(
self: Pin<&'pin mut Self>,
factory: impl FnOnce(YieldSlot<'yield_slot, Item>, Args) -> F,
args: Args
) where
Item: 'yield_slot,
[src]
self: Pin<&'pin mut Self>,
factory: impl FnOnce(YieldSlot<'yield_slot, Item>, Args) -> F,
args: Args
) where
Item: 'yield_slot,
Fill the memory reserved by GeneratorFn::empty
()
with an instance of
the generator function / factory.
pub fn resume(self: Pin<&mut Self>) -> GeneratorState<Item, F::Output>
[src]
Associated method version of Generator::resume
.
Trait Implementations
impl<Item, F: Future> Generator for GeneratorFn<Item, F>
[src]
Auto Trait Implementations
impl<Item, F> Send for GeneratorFn<Item, F> where
F: Send,
Item: Send,
F: Send,
Item: Send,
impl<Item, F> !Sync for GeneratorFn<Item, F>
impl<Item, F> Unpin for GeneratorFn<Item, F> where
F: Unpin,
Item: Unpin,
F: Unpin,
Item: Unpin,
impl<Item, F> UnwindSafe for GeneratorFn<Item, F> where
F: UnwindSafe,
Item: UnwindSafe,
F: UnwindSafe,
Item: UnwindSafe,
impl<Item, F> !RefUnwindSafe for GeneratorFn<Item, F>
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,