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}