1use crate::{ComponentMap, Keyed, WithArgs};
2
3impl<Key, Args, Comp, FnInit> ComponentMap<Key, Args, Comp, FnInit> {
4 pub fn init(args: impl IntoIterator<Item = (Key, Args)>, init: FnInit) -> Self
5 where
6 Key: Eq + std::hash::Hash,
7 FnInit: Fn(&Args) -> Comp,
8 {
9 let map = args
10 .into_iter()
11 .map(|(key, args)| {
12 (
13 key,
14 WithArgs {
15 component: (init)(&args),
16 args,
17 },
18 )
19 })
20 .collect();
21
22 Self { map, init }
23 }
24
25 pub fn reinit_all(&mut self) -> impl Iterator<Item = Keyed<&Key, Comp>>
26 where
27 FnInit: Fn(&Args) -> Comp,
28 {
29 self.map.iter_mut().map(|(key, component)| {
30 let next = (self.init)(&component.args);
31 let prev = std::mem::replace(&mut component.component, next);
32 Keyed::new(key, prev)
33 })
34 }
35
36 pub fn reinit(
37 &mut self,
38 keys: impl IntoIterator<Item = Key>,
39 ) -> impl Iterator<Item = Keyed<Key, Option<Comp>>>
40 where
41 Key: Eq + std::hash::Hash,
42 FnInit: Fn(&Args) -> Comp,
43 {
44 keys.into_iter().map(|key| {
45 let prev = self.map.get_mut(&key).map(|component| {
46 let next = (self.init)(&component.args);
47 std::mem::replace(&mut component.component, next)
48 });
49
50 Keyed::new(key, prev)
51 })
52 }
53
54 pub fn update(
55 &mut self,
56 updates: impl IntoIterator<Item = (Key, Args)>,
57 ) -> impl Iterator<Item = Keyed<Key, Option<WithArgs<Args, Comp>>>>
58 where
59 Key: Clone + Eq + std::hash::Hash,
60 FnInit: Fn(&Args) -> Comp,
61 {
62 updates.into_iter().map(move |(key, args)| {
63 let prev = self.map.insert(
64 key.clone(),
65 WithArgs {
66 component: (self.init)(&args),
67 args,
68 },
69 );
70
71 Keyed::new(key, prev)
72 })
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use std::sync::{Arc, Mutex};
80
81 #[derive(Debug, Clone, PartialEq, Eq)]
82 struct Counter(usize);
83
84 #[derive(Debug, Clone, PartialEq, Eq)]
85 struct Args {
86 value: usize,
87 }
88
89 #[test]
90 fn test_init() {
91 let init = |args: &Args| Counter(args.value);
92 let manager = ComponentMap::init(
93 [("key1", Args { value: 1 }), ("key2", Args { value: 2 })],
94 init,
95 );
96
97 assert_eq!(manager.components().len(), 2);
98 assert_eq!(
99 manager.components().get("key1").unwrap().component,
100 Counter(1)
101 );
102 assert_eq!(
103 manager.components().get("key2").unwrap().component,
104 Counter(2)
105 );
106 assert_eq!(manager.components().get("key1").unwrap().args.value, 1);
107 }
108
109 #[test]
110 fn test_init_empty() {
111 let init = |args: &Args| Counter(args.value);
112 let manager: ComponentMap<&str, Args, Counter, _> = ComponentMap::init([], init);
113
114 assert_eq!(manager.components().len(), 0);
115 }
116
117 #[test]
118 fn test_init_multiple_components() {
119 let init = |args: &Args| Counter(args.value * 10);
120 let manager = ComponentMap::init(
121 [
122 ("a", Args { value: 1 }),
123 ("b", Args { value: 2 }),
124 ("c", Args { value: 3 }),
125 ("d", Args { value: 4 }),
126 ],
127 init,
128 );
129
130 assert_eq!(manager.components().len(), 4);
131 assert_eq!(
132 manager.components().get("a").unwrap().component,
133 Counter(10)
134 );
135 assert_eq!(
136 manager.components().get("d").unwrap().component,
137 Counter(40)
138 );
139 }
140
141 #[test]
142 fn test_reinit_all() {
143 let call_count = Arc::new(Mutex::new(0));
144 let call_count_clone = call_count.clone();
145
146 let init = move |args: &Args| {
147 *call_count_clone.lock().unwrap() += 1;
148 Counter(args.value * 2)
149 };
150
151 let mut manager = ComponentMap::init(
152 [("key1", Args { value: 1 }), ("key2", Args { value: 2 })],
153 init,
154 );
155
156 let prev_components: Vec<_> = manager.reinit_all().collect();
158
159 assert_eq!(prev_components.len(), 2);
160
161 let prev_values: Vec<_> = prev_components.iter().map(|k| &k.value.0).collect();
163 assert!(prev_values.contains(&&2));
164 assert!(prev_values.contains(&&4));
165
166 assert_eq!(
168 manager.components().get("key1").unwrap().component,
169 Counter(2)
170 );
171 assert_eq!(
172 manager.components().get("key2").unwrap().component,
173 Counter(4)
174 );
175
176 assert_eq!(*call_count.lock().unwrap(), 4);
178 }
179
180 #[test]
181 fn test_reinit_all_empty() {
182 let init = |args: &Args| Counter(args.value);
183 let mut manager: ComponentMap<&str, Args, Counter, _> = ComponentMap::init([], init);
184
185 let results: Vec<_> = manager.reinit_all().collect();
186 assert_eq!(results.len(), 0);
187 }
188
189 #[test]
190 fn test_reinit_existing_key() {
191 let init = |args: &Args| Counter(args.value * 2);
192
193 let mut manager = ComponentMap::init(
194 [("key1", Args { value: 1 }), ("key2", Args { value: 2 })],
195 init,
196 );
197
198 let results: Vec<_> = manager.reinit(["key1"]).collect();
199
200 assert_eq!(results.len(), 1);
201 assert_eq!(results[0].key, "key1");
202 assert_eq!(results[0].value, Some(Counter(2)));
203
204 assert_eq!(
206 manager.components().get("key1").unwrap().component,
207 Counter(2)
208 );
209 assert_eq!(
211 manager.components().get("key2").unwrap().component,
212 Counter(4)
213 );
214 }
215
216 #[test]
217 fn test_reinit_multiple_keys() {
218 let init = |args: &Args| Counter(args.value * 3);
219
220 let mut manager = ComponentMap::init(
221 [
222 ("key1", Args { value: 1 }),
223 ("key2", Args { value: 2 }),
224 ("key3", Args { value: 3 }),
225 ],
226 init,
227 );
228
229 let results: Vec<_> = manager.reinit(["key1", "key3"]).collect();
230
231 assert_eq!(results.len(), 2);
232 assert_eq!(
233 manager.components().get("key1").unwrap().component,
234 Counter(3)
235 );
236 assert_eq!(
237 manager.components().get("key2").unwrap().component,
238 Counter(6)
239 );
240 assert_eq!(
241 manager.components().get("key3").unwrap().component,
242 Counter(9)
243 );
244 }
245
246 #[test]
247 fn test_reinit_nonexistent_key() {
248 let init = |args: &Args| Counter(args.value);
249
250 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
251
252 let results: Vec<_> = manager.reinit(["nonexistent"]).collect();
253
254 assert_eq!(results.len(), 1);
255 assert_eq!(results[0].key, "nonexistent");
256 assert_eq!(results[0].value, None);
257
258 assert_eq!(manager.components().len(), 1);
260 }
261
262 #[test]
263 fn test_reinit_mixed_existent_and_nonexistent() {
264 let init = |args: &Args| Counter(args.value);
265
266 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
267
268 let results: Vec<_> = manager.reinit(["key1", "nonexistent"]).collect();
269
270 assert_eq!(results.len(), 2);
271 assert!(results[0].value.is_some() || results[1].value.is_some());
272 assert!(results[0].value.is_none() || results[1].value.is_none());
273 }
274
275 #[test]
276 fn test_update_existing_key() {
277 let init = |args: &Args| Counter(args.value);
278
279 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
280
281 let results: Vec<_> = manager.update([("key1", Args { value: 10 })]).collect();
282
283 assert_eq!(results.len(), 1);
284 assert_eq!(results[0].key, "key1");
285 assert!(results[0].value.is_some());
286 assert_eq!(results[0].value.as_ref().unwrap().component, Counter(1));
287 assert_eq!(results[0].value.as_ref().unwrap().args.value, 1);
288
289 assert_eq!(
291 manager.components().get("key1").unwrap().component,
292 Counter(10)
293 );
294 assert_eq!(manager.components().get("key1").unwrap().args.value, 10);
295 }
296
297 #[test]
298 fn test_update_new_key() {
299 let init = |args: &Args| Counter(args.value);
300
301 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
302
303 let results: Vec<_> = manager.update([("key2", Args { value: 20 })]).collect();
304
305 assert_eq!(results.len(), 1);
306 assert_eq!(results[0].key, "key2");
307 assert!(results[0].value.is_none());
308
309 assert_eq!(manager.components().len(), 2);
311 assert_eq!(
312 manager.components().get("key2").unwrap().component,
313 Counter(20)
314 );
315 }
316
317 #[test]
318 fn test_update_multiple_keys() {
319 let init = |args: &Args| Counter(args.value);
320
321 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
322
323 let results: Vec<_> = manager
324 .update([
325 ("key1", Args { value: 10 }),
326 ("key2", Args { value: 20 }),
327 ("key3", Args { value: 30 }),
328 ])
329 .collect();
330
331 assert_eq!(results.len(), 3);
332 assert_eq!(manager.components().len(), 3);
333 assert_eq!(
334 manager.components().get("key1").unwrap().component,
335 Counter(10)
336 );
337 assert_eq!(
338 manager.components().get("key2").unwrap().component,
339 Counter(20)
340 );
341 assert_eq!(
342 manager.components().get("key3").unwrap().component,
343 Counter(30)
344 );
345 }
346
347 #[test]
348 fn test_components_accessors() {
349 let init = |args: &Args| Counter(args.value);
350 let mut manager = ComponentMap::init([("key1", Args { value: 1 })], init);
351
352 assert_eq!(manager.components().len(), 1);
354 assert_eq!(
355 manager.components().get("key1").unwrap().component,
356 Counter(1)
357 );
358
359 manager.components_mut().get_mut("key1").unwrap().component = Counter(999);
361 assert_eq!(
362 manager.components().get("key1").unwrap().component,
363 Counter(999)
364 );
365 }
366
367 #[test]
368 fn test_fn_init_accessor() {
369 let init = |args: &Args| Counter(args.value * 5);
370 let manager = ComponentMap::init([("key1", Args { value: 1 })], init);
371
372 let fn_init = manager.fn_init();
373 let result = (fn_init)(&Args { value: 10 });
374 assert_eq!(result, Counter(50));
375 }
376}