[][src]Macro gc_sequence::make_sequencable_arena

macro_rules! make_sequencable_arena {
    ($module:ident, $root:ident) => { ... };
    ($vis:vis $module:ident, $root:ident) => { ... };
    (@impl $modvis:vis, $innervis:vis, $module:ident, $root:ident) => { ... };
}

Creates a set of types for running "sequences" on gc_arena "arena" types.

Takes two parameters, the first is the name of a module that will be created, the second is the name of a type that can be made into an "arena" type with gc_arena::make_arena.

The module will contain two accessible types, module::Arena module::Sequencer. The Arena type is the same as what would be produced by gc_arena::make_arena, but has a single extra method Arena::sequence. Arena::sequence can be used to produce a module::Sequencer, which can then be stepped until a result is produced.


#[derive(Collect)]
#[collect(empty_drop)]
struct TestRoot<'gc> {
    test: Gc<'gc, i32>,
}

make_sequencable_arena!(test_sequencer, TestRoot);
use test_sequencer::Arena as TestArena;

fn main() {
    let arena = TestArena::new(ArenaParameters::default(), |mc| TestRoot {
        test: Gc::allocate(mc, 42),
    });

    let mut sequence = arena.sequence(|root| {
        gc_sequence::from_fn_with(root.test, |_, test| {
            *test + 10
        })
        .then(|_, r| r - 20)
        .then(|_, r| r - 30)
        .then(|_, r| r + 2)
        .boxed()
    });

    loop {
        match sequence.step() {
            Ok((_, output)) => {
                assert_eq!(output, 4);
                return;
            }
            Err(s) => sequence = s,
        }
    }
}