Trait pushgen::Generator[][src]

pub trait Generator {
    type Output;
    fn run(
        &mut self,
        output: impl FnMut(Self::Output) -> ValueResult
    ) -> GeneratorResult; fn try_advance(&mut self, n: NonZeroUsize) -> (usize, GeneratorResult) { ... } }
Expand description

Trait for generating values into a closure.

When a Generator is run() it generates values that are fed an output closure. It continues to feed values to the closure for as long as it can, unless the closure returns ValueResult::Stop.

When all values have been generated the run() method returns GeneratorResult::Complete. If output returns ValueResult::Stop for any value the generator must not call output with any further values and return GeneratorResult::Stopped as well.

The generator must not assume that it won’t be called again after it returns.

Example

A generic generator can be written like this:

use pushgen::{Generator, ValueResult, GeneratorResult};
struct GenericGenerator<Out, Gen>
where
    Gen: FnMut() -> Option<Out>,
{
    generator: Gen,
}

impl<Out, Gen> Generator for GenericGenerator<Out, Gen>
    where
        Gen: FnMut() -> Option<Out>,
{
    type Output = Out;

    fn run(&mut self, mut output: impl FnMut(Self::Output) -> ValueResult) -> GeneratorResult {
        while let Some(value) = (self.generator)() {
            if output(value) == ValueResult::Stop {
                return GeneratorResult::Stopped;
            }
        }
        GeneratorResult::Complete
    }
}

Associated Types

Data-type generated by the generator.

Required methods

Run the generator, emitting values to the output closure.

New values are emitted for as long as the closure returns ValueResult::MoreValues. If the closure returns ValueResult::Stop the generator must return GeneratorResult::Stopped.

Provided methods

Try to advance the generator n values, ignoring them.

This function has a default implementation but should be implemented by adaptors and source generators for additional performance gains.

Returns

The number of steps that the generator was actually advanced, and if the generator was stopped or completed.

Examples

use pushgen::{IntoGenerator, Generator, GeneratorExt, GeneratorResult};
use core::num::NonZeroUsize;
let data = [1, 2, 3, 4, 5];
let mut gen = data.into_gen();
let advance_result = gen.try_advance(NonZeroUsize::new(3).unwrap());
assert_eq!(advance_result, (3, GeneratorResult::Stopped));
assert_eq!(gen.next(), Ok(&4));
assert_eq!(gen.next(), Ok(&5));

Implementors