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