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}