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