fx_rs/core/
arrow.rs

1use super::handler::Handler;
2use crate::{Fx, State};
3use dyn_clone::{DynClone, clone_trait_object};
4
5impl<'f, I, O> Arrow<'f, I, O>
6where
7    O: Clone,
8    I: Clone + 'f,
9{
10    pub fn request(i: I) -> Fx<'f, Self, O>
11    where
12        I: Clone,
13    {
14        State::get().map(|f: Self| f.apply(i))
15    }
16
17    pub fn handler<F, B, V>(f: F) -> Handler<'f, (Self, B), B, V, V>
18    where
19        F: FnOnce(I) -> O + Clone + 'f,
20        B: Clone,
21        V: Clone,
22    {
23        Handler::new(|e: Fx<'f, (Self, B), V>| e.provide_left(Self::new(f)))
24    }
25
26    pub fn new<F>(f: F) -> Self
27    where
28        F: FnOnce(I) -> O + Clone + 'f,
29    {
30        Self(Box::new(f))
31    }
32
33    pub fn apply(self, i: I) -> O {
34        self.0(i)
35    }
36
37    pub fn clone_boxed(&self) -> Box<dyn FnOnce(I) -> O + 'f> {
38        self.0.clone()
39    }
40
41    pub fn adapt<T, U, H, F>(self, cmap: H, fmap: F) -> Arrow<'f, T, U>
42    where
43        T: Clone + 'f,
44        U: Clone,
45        H: FnOnce(T) -> I + Clone + 'f,
46        F: FnOnce(O) -> U + Clone + 'f,
47    {
48        Arrow::new(|t: T| fmap(self.apply(cmap(t))))
49    }
50}
51
52#[derive(Clone)]
53pub struct Arrow<'f, I, O: Clone>(Box<dyn ArrowFn<'f, I, O> + 'f>);
54
55clone_trait_object!(<'f, I, O: Clone> ArrowFn<'f, I, O>);
56
57trait ArrowFn<'f, I, O>: DynClone + FnOnce(I) -> O
58where
59    O: Clone + 'f,
60{
61}
62
63impl<'f, I, O, F> ArrowFn<'f, I, O> for F
64where
65    F: FnOnce(I) -> O + Clone,
66    O: Clone + 'f,
67{
68}