fx_rs/core/
state.rs

1use std::marker::PhantomData;
2
3use crate::Fx;
4
5pub struct State<'f, S: Clone>(PhantomData<&'f S>);
6impl<'f, S: Clone> State<'f, S> {
7    pub fn get() -> Fx<'f, S, S> {
8        Fx::pending(Fx::value)
9    }
10
11    pub fn set(s: S) -> Fx<'f, S, S> {
12        Fx::immediate(s.clone(), s)
13    }
14
15    pub fn map<F>(f: F) -> Fx<'f, S, S>
16    where
17        F: FnOnce(S) -> S + Clone + 'f,
18    {
19        Self::map_m(|s| Fx::value(f(s)))
20    }
21
22    pub fn map_m<F>(f: F) -> Fx<'f, S, S>
23    where
24        F: FnOnce(S) -> Fx<'f, S, S> + Clone + 'f,
25    {
26        Self::get().map_m(f).map_m(State::set)
27    }
28
29    pub fn update<T, F>(f: F) -> Fx<'f, (S, T), S>
30    where
31        T: Clone,
32        F: FnOnce(S) -> Fx<'f, T, S> + Clone + 'f,
33    {
34        Self::get()
35            .flat_map(|s| f(s).flat_map(|s| Self::set(s)))
36            .contra_map(
37                |(s, t): (S, T)| (s.clone(), (t, s)),
38                |_, (_, (t, s))| (s, t),
39            )
40    }
41}