fx_rs/kernel/
ability.rs

1use dyn_clone::{DynClone, clone_trait_object};
2
3use super::Fx;
4
5#[derive(Clone)]
6/// An `Ability` is a function `I -> Fx<S, O>`.
7pub struct Ability<'f, I, S, O>(Box<dyn AbilityFn<'f, I, S, O> + 'f>)
8where
9    S: Clone,
10    O: Clone;
11
12clone_trait_object!(<'f, I: Clone + 'f, S: Clone + 'f, O: Clone + 'f> AbilityFn<'f, I, S, O>);
13pub trait AbilityFn<'f, I: Clone + 'f, S: Clone + 'f, O: Clone + 'f>:
14    DynClone + FnOnce(I) -> Fx<'f, S, O> + 'f
15{
16}
17
18impl<'f, I: Clone + 'f, S: Clone + 'f, O: Clone + 'f, F> AbilityFn<'f, I, S, O> for F where
19    F: FnOnce(I) -> Fx<'f, S, O> + Clone + 'f
20{
21}
22
23impl<'f, I: Clone + 'f, S: Clone + 'f, O: Clone + 'f, F> From<F> for Ability<'f, I, S, O>
24where
25    F: FnOnce(I) -> Fx<'f, S, O> + Clone + 'f,
26{
27    fn from(value: F) -> Self {
28        Ability::new(value)
29    }
30}
31
32impl<'f, I: Clone + 'f, S: Clone + 'f, O: Clone + 'f> From<Ability<'f, I, S, O>>
33    for Box<dyn AbilityFn<'f, I, S, O> + 'f>
34{
35    fn from(value: Ability<'f, I, S, O>) -> Self {
36        value.0
37    }
38}
39
40impl<'f, I, S, O> Ability<'f, I, S, O>
41where
42    S: Clone,
43    O: Clone,
44    I: Clone,
45{
46    pub fn new<F>(f: F) -> Self
47    where
48        F: FnOnce(I) -> Fx<'f, S, O> + Clone + 'f,
49    {
50        Self(Box::new(f))
51    }
52
53    pub fn apply(self, i: I) -> Fx<'f, S, O> {
54        self.0(i)
55    }
56
57    pub fn clone_boxed(&self) -> Box<dyn FnOnce(I) -> Fx<'f, S, O> + 'f> {
58        self.0.clone()
59    }
60}