overture_core/update.rs
1// Left-to-right, in-place function application.
2// Equivalent to Swift's update<A>(_ a: inout A, _ fs: ((inout A) -> Void)...)
3pub fn update<A, F>(a: &mut A, fs: F)
4where
5 F: FnOnce(&mut A),
6{
7 fs(a);
8}
9
10// Left-to-right, in-place function application with multiple functions.
11// Equivalent to Swift's update<A>(_ a: inout A, _ fs: ((inout A) -> Void)...)
12pub fn update_many<A, F>(a: &mut A, fs: impl IntoIterator<Item = F>)
13where
14 F: FnOnce(&mut A),
15{
16 for f in fs {
17 f(a);
18 }
19}
20
21// Left-to-right, in-place throwing function application.
22// Equivalent to Swift's update<A>(_ a: inout A, _ fs: ((inout A) throws -> Void)...) throws
23pub fn update_throwing<A, F, E>(a: &mut A, fs: F) -> Result<(), E>
24where
25 F: FnOnce(&mut A) -> Result<(), E>,
26{
27 fs(a)
28}
29
30// Left-to-right, in-place throwing function application with multiple functions.
31pub fn update_many_throwing<A, F, E>(a: &mut A, fs: impl IntoIterator<Item = F>) -> Result<(), E>
32where
33 F: FnOnce(&mut A) -> Result<(), E>,
34{
35 for f in fs {
36 f(a)?;
37 }
38 Ok(())
39}
40
41// Left-to-right, value-mutable function application.
42// Equivalent to Swift's update<A>(_ a: A, _ fs: ((inout A) -> Void)...) -> A
43pub fn update_value<A, F>(a: A, fs: F) -> A
44where
45 F: FnOnce(&mut A),
46{
47 let mut a = a;
48 fs(&mut a);
49 a
50}
51
52// Left-to-right, value-mutable function application with multiple functions.
53pub fn update_value_many<A, F>(a: A, fs: impl IntoIterator<Item = F>) -> A
54where
55 F: FnOnce(&mut A),
56{
57 let mut a = a;
58 for f in fs {
59 f(&mut a);
60 }
61 a
62}
63
64// Left-to-right, value-mutable, throwing function application.
65// Equivalent to Swift's update<A>(_ a: A, _ fs: ((inout A) throws -> Void)...) throws -> A
66pub fn update_value_throwing<A, F, E>(a: A, fs: F) -> Result<A, E>
67where
68 F: FnOnce(&mut A) -> Result<(), E>,
69{
70 let mut a = a;
71 fs(&mut a)?;
72 Ok(a)
73}
74
75// Left-to-right, value-mutable, throwing function application with multiple functions.
76pub fn update_value_many_throwing<A, F, E>(a: A, fs: impl IntoIterator<Item = F>) -> Result<A, E>
77where
78 F: FnOnce(&mut A) -> Result<(), E>,
79{
80 let mut a = a;
81 for f in fs {
82 f(&mut a)?;
83 }
84 Ok(a)
85}
86
87// Left-to-right, reference-mutable function application.
88// Equivalent to Swift's updateObject<A: AnyObject>(_ a: A, _ fs: ((A) -> Void)...) -> A
89pub fn update_object<A, F>(a: A, fs: F) -> A
90where
91 F: FnOnce(&mut A),
92{
93 let mut a = a;
94 fs(&mut a);
95 a
96}
97
98// Left-to-right, reference-mutable function application with multiple functions.
99pub fn update_object_many<A, F>(a: A, fs: impl IntoIterator<Item = F>) -> A
100where
101 F: FnOnce(&mut A),
102{
103 let mut a = a;
104 for f in fs {
105 f(&mut a);
106 }
107 a
108}
109
110// Left-to-right, reference-mutable, throwing function application.
111// Equivalent to Swift's updateObject<A: AnyObject>(_ a: A, _ fs: ((A) throws -> Void)...) throws -> A
112pub fn update_object_throwing<A, F, E>(a: A, fs: F) -> Result<A, E>
113where
114 F: FnOnce(&mut A) -> Result<(), E>,
115{
116 let mut a = a;
117 fs(&mut a)?;
118 Ok(a)
119}
120
121// Left-to-right, reference-mutable, throwing function application with multiple functions.
122pub fn update_object_many_throwing<A, F, E>(a: A, fs: impl IntoIterator<Item = F>) -> Result<A, E>
123where
124 F: FnOnce(&mut A) -> Result<(), E>,
125{
126 let mut a = a;
127 for f in fs {
128 f(&mut a)?;
129 }
130 Ok(a)
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_update() {
139 let mut x = 5;
140 update(&mut x, |a| *a += 3);
141 assert_eq!(x, 8);
142 }
143
144 // #[test]
145 // fn test_update_many() {
146 // let mut x = 5;
147 // update_many(&mut x, [|a| *a += 3, |a| *a *= 2]);
148 // assert_eq!(x, 16); // (5 + 3) * 2 = 16
149 // }
150
151 // #[test]
152 // fn test_update_throwing() {
153 // let mut x = 5;
154 // let result = update_throwing(&mut x, |a| {
155 // *a += 3;
156 // Ok(())
157 // });
158 // assert_eq!(result, Ok(()));
159 // assert_eq!(x, 8);
160 // }
161
162 // #[test]
163 // fn test_update_value() {
164 // let x = 5;
165 // let result = update_value(x, |a| *a += 3);
166 // assert_eq!(result, 8);
167 // assert_eq!(x, 5); // original unchanged
168 // }
169
170 // #[test]
171 // fn test_update_value_many() {
172 // let x = 5;
173 // let result = update_value_many(x, [|a| *a += 3, |a| *a *= 2]);
174 // assert_eq!(result, 16); // (5 + 3) * 2 = 16
175 // assert_eq!(x, 5); // original unchanged
176 // }
177
178 // #[test]
179 // fn test_update_object() {
180 // let x = 5;
181 // let result = update_object(x, |a| *a += 3);
182 // assert_eq!(result, 8);
183 // assert_eq!(x, 5); // original unchanged
184 // }
185
186 // #[test]
187 // fn test_update_object_many() {
188 // let x = 5;
189 // let result = update_object_many(x, [|a| *a += 3, |a| *a *= 2]);
190 // assert_eq!(result, 16); // (5 + 3) * 2 = 16
191 // assert_eq!(x, 5); // original unchanged
192 // }
193
194 // #[test]
195 // fn test_update_value_throwing() {
196 // let x = 5;
197 // let result = update_value_throwing(x, |a| {
198 // *a += 3;
199 // Ok(())
200 // });
201 // assert_eq!(result, Ok(8));
202 // assert_eq!(x, 5); // original unchanged
203 // }
204
205 // #[test]
206 // fn test_update_value_many_throwing() {
207 // let x = 5;
208 // let result = update_value_many_throwing(x, [|a| { *a += 3; Ok(()) }, |a| { *a *= 2; Ok(()) }]);
209 // assert_eq!(result, Ok(16)); // (5 + 3) * 2 = 16
210 // assert_eq!(x, 5); // original unchanged
211 // }
212
213 // #[test]
214 // fn test_update_object_throwing() {
215 // let x = 5;
216 // let result = update_object_throwing(x, |a| {
217 // *a += 3;
218 // Ok(())
219 // });
220 // assert_eq!(result, Ok(8));
221 // assert_eq!(x, 5); // original unchanged
222 // }
223
224 // #[test]
225 // fn test_update_object_many_throwing() {
226 // let x = 5;
227 // let result = update_object_many_throwing(x, [|a| { *a += 3; Ok(()) }, |a| { *a *= 2; Ok(()) }]);
228 // assert_eq!(result, Ok(16)); // (5 + 3) * 2 = 16
229 // assert_eq!(x, 5); // original unchanged
230 // }
231}