ltrait_extra/
action.rs

1use ltrait::{Action, action::ActionWrapper};
2
3pub trait ActionExt: Action
4where
5    <Self as Action>::Context: Sync + Send,
6{
7    fn to_if<Cushion, F, TransF>(self, f: F, transformer: TransF) -> impl Action<Context = Cushion>
8    where
9        Self: Sized,
10        Cushion: Sync + Send,
11        F: Fn(&Cushion) -> bool + Send,
12        TransF: Fn(&Cushion) -> <Self as Action>::Context + Send,
13    {
14        ActionIf::new(self, f, transformer)
15    }
16}
17
18pub struct ActionIf<T, Ctx, F>
19where
20    T: Action<Context = Ctx>,
21    F: Fn(&Ctx) -> bool + Send,
22    Ctx: Sync,
23{
24    inner: T,
25
26    f: F,
27}
28
29impl<Cushion, F, Inner, TransF, Ctx>
30    ActionIf<ActionWrapper<Ctx, Inner, TransF, Cushion>, Cushion, F>
31where
32    F: Fn(&Cushion) -> bool + Send,
33    Cushion: Sync + Send,
34    TransF: Fn(&Cushion) -> Ctx + Send,
35    Inner: Action<Context = Ctx>,
36    Ctx: Sync + Send,
37{
38    pub fn new(inner: Inner, f: F, transformer: TransF) -> Self {
39        Self {
40            inner: ActionWrapper::new(inner, transformer),
41            f,
42            // _ctx: PhantomData,
43        }
44    }
45}
46
47impl<T, Ctx, F> Action for ActionIf<T, Ctx, F>
48where
49    T: Action<Context = Ctx>,
50    F: Fn(&Ctx) -> bool + Send,
51    Ctx: Sync + Send,
52{
53    type Context = Ctx;
54
55    fn act(&self, ctx: &Self::Context) -> ltrait::color_eyre::eyre::Result<()> {
56        if (self.f)(ctx) {
57            self.inner.act(ctx)
58        } else {
59            Ok(())
60        }
61    }
62}