ltrait_extra/
action.rs

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