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}