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 }
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}