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