1use std::{cell::RefCell, rc::Rc};
2
3pub fn get<Root, Value>(getter: impl Fn(&Root) -> Value + Clone + 'static) -> impl Fn(Root) -> Value
5where
6 Value: Clone + 'static,
7{
8 move |root: Root| getter(&root)
9}
10
11pub fn set<Root, Value>(
13 setter: impl Fn(&mut Root, Value) + Clone + 'static,
14 getter: impl Fn(&Root) -> Value + Clone + 'static,
15 value: Value,
16) -> impl Fn(Root) -> Root
17where
18 Root: Clone + 'static,
19 Value: Clone + 'static,
20{
21 move |root: Root| {
22 let mut copy = root.clone();
23 setter(&mut copy, value.clone());
24 copy
25 }
26}
27
28pub fn mut_<Root, Value>(
30 setter: impl Fn(&mut Root, Value) + Clone + 'static,
31 getter: impl Fn(&mut Root) -> &mut Value + Clone + 'static,
32 value: Value,
33) -> impl FnMut(&mut Root)
34where
35 Root: 'static,
36 Value: Clone + 'static,
37{
38 move |root: &mut Root| {
39 setter(root, value.clone());
40 }
41}
42
43pub fn prop<Root, Value>(
55 setter: impl Fn(&mut Root, Value) + Clone + 'static,
56 getter: impl Fn(&Root) -> Value + Clone + 'static,
57) -> impl Fn(Box<dyn Fn(Value) -> Value>) -> Box<dyn Fn(Root) -> Root>
58where
59 Root: Clone + 'static,
60 Value: Clone + 'static,
61{
62 let setter = Rc::new(setter);
63 let getter = Rc::new(getter);
64 move |update: Box<dyn Fn(Value) -> Value>| {
65 let setter = setter.clone();
66 let getter = getter.clone();
67 Box::new(move |root: Root| {
68 let mut copy = root.clone();
69 let value = getter(©);
70 let new_value = update(value);
71 setter(&mut copy, new_value);
72 copy
73 })
74 }
75}
76
77pub fn over<Root, Value>(
79 setter: impl Fn(&mut Root, Value) + Clone + 'static,
80 getter: impl Fn(&Root) -> Value + Clone + 'static,
81 update: impl Fn(Value) -> Value + 'static,
82) -> impl Fn(Root) -> Root
83where
84 Root: Clone + 'static,
85 Value: Clone + 'static,
86{
87 let prop_fn = prop(setter, getter);
88 prop_fn(Box::new(update))
89}
90
91pub fn mprop<Root, Value>(
106 setter: impl Fn(&mut Root, Value) + Clone + 'static,
107 getter: impl Fn(&mut Root) -> &mut Value + Clone + 'static,
108) -> impl Fn(Box<dyn FnMut(&mut Value)>) -> Box<dyn FnMut(&mut Root)>
109where
110 Root: 'static,
111 Value: 'static,
112{
113 let setter = Rc::new(setter);
114 let getter = Rc::new(getter);
115 move |mut update: Box<dyn FnMut(&mut Value)>| {
116 let setter = setter.clone();
117 let getter = getter.clone();
118 Box::new(move |root: &mut Root| {
119 let value = getter(root);
120 update(value);
121 })
122 }
123}
124
125pub fn mver<Root, Value>(
127 setter: impl Fn(&mut Root, Value) + Clone + 'static,
128 getter: impl Fn(&mut Root) -> &mut Value + Clone + 'static,
129 mut update: impl FnMut(&mut Value) + 'static,
130) -> impl FnMut(&mut Root)
131where
132 Root: 'static,
133 Value: 'static,
134{
135 let mprop_fn = mprop(setter, getter);
136 let boxed_update = Box::new(update);
137 let mut setter_fn = mprop_fn(boxed_update);
138 move |root| setter_fn(root)
139}
140
141