macro_rules! make_sequencable_arena {
($module:ident, $root:ident) => { ... };
($vis:vis $module:ident, $root:ident) => { ... };
(@impl $modvis:vis, $innervis:vis, $module:ident, $root:ident) => { ... };
}
Expand description
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(no_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,
}
}
}