1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use gc_arena::{Collect, MutationContext, StaticCollect}; use crate::Sequence; #[must_use = "sequences do nothing unless stepped"] #[derive(Debug, Collect)] #[collect(no_drop)] pub enum Then<'gc, S, F> where S: Sequence<'gc>, { First(S, Option<StaticCollect<F>>), Second(Option<(S::Output, StaticCollect<F>)>), } impl<'gc, S, F> Then<'gc, S, F> where S: Sequence<'gc>, { pub fn new(s: S, f: F) -> Then<'gc, S, F> { Then::First(s, Some(StaticCollect(f))) } } impl<'gc, S, F, R> Sequence<'gc> for Then<'gc, S, F> where S: Sequence<'gc>, S::Output: Collect, F: 'static + FnOnce(MutationContext<'gc, '_>, S::Output) -> R, { type Output = R; fn step(&mut self, mc: MutationContext<'gc, '_>) -> Option<R> { match self { Then::First(seq, f) => match seq.step(mc) { Some(res) => { *self = Then::Second(Some((res, f.take().unwrap()))); None } None => None, }, Then::Second(sec) => { let (res, f) = sec.take().expect("cannot step a finished sequence"); Some(f.0(mc, res)) } } } } #[must_use = "sequences do nothing unless stepped"] #[derive(Debug, Collect)] #[collect(no_drop)] pub enum ThenWith<'gc, S, C, F> where S: Sequence<'gc>, { First(S, Option<(C, StaticCollect<F>)>), Second(Option<(C, S::Output, StaticCollect<F>)>), } impl<'gc, S, C, F> ThenWith<'gc, S, C, F> where S: Sequence<'gc>, { pub fn new(s: S, c: C, f: F) -> ThenWith<'gc, S, C, F> { ThenWith::First(s, Some((c, StaticCollect(f)))) } } impl<'gc, S, C, F, R> Sequence<'gc> for ThenWith<'gc, S, C, F> where S: Sequence<'gc>, S::Output: Collect, C: Collect, F: 'static + FnOnce(MutationContext<'gc, '_>, C, S::Output) -> R, { type Output = R; fn step(&mut self, mc: MutationContext<'gc, '_>) -> Option<R> { match self { ThenWith::First(seq, cf) => match seq.step(mc) { Some(res) => { let (c, f) = cf.take().unwrap(); *self = ThenWith::Second(Some((c, res, f))); None } None => None, }, ThenWith::Second(sec) => { let (c, res, f) = sec.take().expect("cannot step a finished sequence"); Some(f.0(mc, c, res)) } } } }