gc_sequence/
and_then.rs

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}