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 struct Map<S, F>(S, Option<StaticCollect<F>>);
9
10impl<S, F> Map<S, F> {
11 pub fn new(s: S, f: F) -> Map<S, F> {
12 Map(s, Some(StaticCollect(f)))
13 }
14}
15
16impl<'gc, S, F, R> Sequence<'gc> for Map<S, F>
17where
18 S: Sequence<'gc>,
19 F: 'static + FnOnce(S::Output) -> R,
20{
21 type Output = R;
22
23 fn step(&mut self, mc: MutationContext<'gc, '_>) -> Option<R> {
24 match self.0.step(mc) {
25 Some(res) => Some(self.1.take().expect("cannot step a finished sequence").0(
26 res,
27 )),
28 None => None,
29 }
30 }
31}
32
33#[must_use = "sequences do nothing unless stepped"]
34#[derive(Debug, Collect)]
35#[collect(no_drop)]
36pub struct MapWith<S, C, F>(S, Option<(C, StaticCollect<F>)>);
37
38impl<S, C, F> MapWith<S, C, F> {
39 pub fn new(s: S, c: C, f: F) -> MapWith<S, C, F> {
40 MapWith(s, Some((c, StaticCollect(f))))
41 }
42}
43
44impl<'gc, S, C, F, R> Sequence<'gc> for MapWith<S, C, F>
45where
46 S: Sequence<'gc>,
47 C: Collect,
48 F: 'static + FnOnce(C, S::Output) -> R,
49{
50 type Output = R;
51
52 fn step(&mut self, mc: MutationContext<'gc, '_>) -> Option<Self::Output> {
53 match self.0.step(mc) {
54 Some(res) => {
55 let (c, StaticCollect(f)) = self.1.take().expect("cannot step a finished sequence");
56 Some(f(c, res))
57 }
58 None => None,
59 }
60 }
61}