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