1use super::*;
2
3pub struct MapRef<I, O, S> {
5 source: S,
6 map: Arc<dyn Fn(&I) -> &O + Send + Sync>,
7}
8
9pub struct WeakMapRef<I, O, S> {
11 source: S,
12 map: Arc<dyn Fn(&I) -> &O + Send + Sync>,
13}
14
15impl<I: VarValue, O: VarValue, S: Var<I>> MapRef<I, O, S> {
16 pub(super) fn new(source: S, map: Arc<dyn Fn(&I) -> &O + Send + Sync>) -> Self {
17 MapRef { source, map }
18 }
19}
20
21impl<I: VarValue, O: VarValue, S: Var<I>> crate::private::Sealed for MapRef<I, O, S> {}
22impl<I: VarValue, O: VarValue, S: WeakVar<I>> crate::private::Sealed for WeakMapRef<I, O, S> {}
23
24impl<I: VarValue, O: VarValue, S: Var<I>> Clone for MapRef<I, O, S> {
25 fn clone(&self) -> Self {
26 Self {
27 source: self.source.clone(),
28 map: self.map.clone(),
29 }
30 }
31}
32impl<I: VarValue, O: VarValue, S: WeakVar<I>> Clone for WeakMapRef<I, O, S> {
33 fn clone(&self) -> Self {
34 Self {
35 source: self.source.clone(),
36 map: self.map.clone(),
37 }
38 }
39}
40
41impl<I: VarValue, O: VarValue, S: Var<I>> AnyVar for MapRef<I, O, S> {
42 fn clone_any(&self) -> BoxedAnyVar {
43 Box::new(self.clone())
44 }
45
46 fn as_any(&self) -> &dyn Any {
47 self
48 }
49
50 fn as_unboxed_any(&self) -> &dyn Any {
51 self
52 }
53
54 fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
55 let me: BoxedVar<O> = self;
56 Box::new(me)
57 }
58
59 fn var_type_id(&self) -> TypeId {
60 TypeId::of::<O>()
61 }
62
63 fn get_any(&self) -> Box<dyn AnyVarValue> {
64 Box::new(self.get())
65 }
66
67 fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
68 self.with(|v| read(v))
69 }
70
71 fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
72 self.with_new(|v| read(v)).is_some()
73 }
74
75 fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
76 Err(VarIsReadOnlyError {
77 capabilities: self.capabilities(),
78 })
79 }
80
81 fn last_update(&self) -> VarUpdateId {
82 self.source.last_update()
83 }
84
85 fn is_contextual(&self) -> bool {
86 self.source.is_contextual()
87 }
88
89 fn capabilities(&self) -> VarCapability {
90 self.source.capabilities().as_read_only()
91 }
92
93 fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
94 let map = self.map.clone();
95 self.source.hook_any(Box::new(move |args| {
96 if let Some(value) = args.downcast_value() {
97 let value = map(value);
98 pos_modify_action(&AnyVarHookArgs::new(value, args.update(), args.tags()))
99 } else {
100 true
101 }
102 }))
103 }
104
105 fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
106 self.source.hook_animation_stop(handler)
107 }
108
109 fn strong_count(&self) -> usize {
110 self.source.strong_count()
111 }
112
113 fn weak_count(&self) -> usize {
114 self.source.weak_count()
115 }
116
117 fn actual_var_any(&self) -> BoxedAnyVar {
118 Box::new(self.clone().actual_var())
119 }
120
121 fn downgrade_any(&self) -> BoxedAnyWeakVar {
122 Box::new(self.downgrade())
123 }
124
125 fn is_animating(&self) -> bool {
126 self.source.is_animating()
127 }
128
129 fn modify_importance(&self) -> usize {
130 self.source.modify_importance()
131 }
132
133 fn var_ptr(&self) -> VarPtr {
134 self.source.var_ptr()
135 }
136
137 fn get_debug(&self) -> Txt {
138 self.with(var_debug)
139 }
140
141 fn update(&self) -> Result<(), VarIsReadOnlyError> {
142 Var::modify(self, var_update)
143 }
144
145 fn map_debug(&self) -> BoxedVar<Txt> {
146 Var::map(self, var_debug).boxed()
147 }
148}
149impl<I: VarValue, O: VarValue, S: WeakVar<I>> AnyWeakVar for WeakMapRef<I, O, S> {
150 fn clone_any(&self) -> BoxedAnyWeakVar {
151 Box::new(self.clone())
152 }
153
154 fn strong_count(&self) -> usize {
155 self.source.strong_count()
156 }
157
158 fn weak_count(&self) -> usize {
159 self.source.weak_count()
160 }
161
162 fn upgrade_any(&self) -> Option<BoxedAnyVar> {
163 self.upgrade().map(|m| Box::new(m) as _)
164 }
165
166 fn as_any(&self) -> &dyn Any {
167 self
168 }
169}
170
171impl<I: VarValue, O: VarValue, S: Var<I>> IntoVar<O> for MapRef<I, O, S> {
172 type Var = Self;
173
174 fn into_var(self) -> Self::Var {
175 self
176 }
177}
178
179impl<I: VarValue, O: VarValue, S: Var<I>> Var<O> for MapRef<I, O, S> {
180 type ReadOnly = Self;
181
182 type ActualVar = MapRef<I, O, S::ActualVar>;
183
184 type Downgrade = WeakMapRef<I, O, S::Downgrade>;
185
186 type Map<MO: VarValue> = BoxedVar<MO>;
187 type MapBidi<MO: VarValue> = BoxedVar<MO>;
188
189 type FlatMap<OF: VarValue, V: Var<OF>> = BoxedVar<OF>;
190
191 type FilterMap<OF: VarValue> = BoxedVar<OF>;
192 type FilterMapBidi<OF: VarValue> = BoxedVar<OF>;
193
194 type MapRef<OM: VarValue> = types::MapRef<O, OM, Self>;
195 type MapRefBidi<OM: VarValue> = types::MapRef<O, OM, Self>;
196
197 type Easing = BoxedVar<O>;
198
199 fn with<R, F>(&self, read: F) -> R
200 where
201 F: FnOnce(&O) -> R,
202 {
203 self.source.with(|val| {
204 let val = (self.map)(val);
205 read(val)
206 })
207 }
208
209 fn modify<F>(&self, _: F) -> Result<(), VarIsReadOnlyError>
210 where
211 F: FnOnce(&mut VarModify<O>) + 'static,
212 {
213 Err(VarIsReadOnlyError {
214 capabilities: self.capabilities(),
215 })
216 }
217
218 fn actual_var(self) -> Self::ActualVar {
219 MapRef {
220 source: self.source.actual_var(),
221 map: self.map,
222 }
223 }
224
225 fn downgrade(&self) -> Self::Downgrade {
226 WeakMapRef {
227 source: self.source.downgrade(),
228 map: self.map.clone(),
229 }
230 }
231
232 fn into_value(self) -> O {
233 self.get()
234 }
235
236 fn read_only(&self) -> Self::ReadOnly {
237 self.clone()
238 }
239
240 fn map<MO, M>(&self, map: M) -> Self::Map<MO>
241 where
242 MO: VarValue,
243 M: FnMut(&O) -> MO + Send + 'static,
244 {
245 var_map_mixed(self, map)
246 }
247
248 fn map_bidi<MO, M, B>(&self, map: M, map_back: B) -> Self::MapBidi<MO>
249 where
250 MO: VarValue,
251 M: FnMut(&O) -> MO + Send + 'static,
252 B: FnMut(&MO) -> O + Send + 'static,
253 {
254 var_map_bidi_mixed(self, map, map_back)
255 }
256
257 fn flat_map<OF, V, M>(&self, map: M) -> Self::FlatMap<OF, V>
258 where
259 OF: VarValue,
260 V: Var<OF>,
261 M: FnMut(&O) -> V + Send + 'static,
262 {
263 var_flat_map_mixed(self, map)
264 }
265
266 fn filter_map<OF, M, IF>(&self, map: M, fallback: IF) -> Self::FilterMap<OF>
267 where
268 OF: VarValue,
269 M: FnMut(&O) -> Option<OF> + Send + 'static,
270 IF: Fn() -> OF + Send + Sync + 'static,
271 {
272 var_filter_map_mixed(self, map, fallback)
273 }
274
275 fn filter_map_bidi<OF, M, B, IF>(&self, map: M, map_back: B, fallback: IF) -> Self::FilterMapBidi<OF>
276 where
277 OF: VarValue,
278 M: FnMut(&O) -> Option<OF> + Send + 'static,
279 B: FnMut(&OF) -> Option<O> + Send + 'static,
280 IF: Fn() -> OF + Send + Sync + 'static,
281 {
282 var_filter_map_bidi_mixed(self, map, map_back, fallback)
283 }
284
285 fn map_ref<OM, M>(&self, map: M) -> Self::MapRef<OM>
286 where
287 OM: VarValue,
288 M: Fn(&O) -> &OM + Send + Sync + 'static,
289 {
290 var_map_ref(self, map)
291 }
292
293 fn map_ref_bidi<OM, M, B>(&self, map: M, _: B) -> Self::MapRefBidi<OM>
294 where
295 OM: VarValue,
296 M: Fn(&O) -> &OM + Send + Sync + 'static,
297 B: Fn(&mut O) -> &mut OM + Send + Sync + 'static,
298 {
299 var_map_ref(self, map)
300 }
301
302 fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
303 where
304 O: Transitionable,
305 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
306 {
307 var_easing_mixed(self, duration, easing)
308 }
309
310 fn easing_with<F, SE>(&self, duration: Duration, easing: F, sampler: SE) -> Self::Easing
311 where
312 O: Transitionable,
313 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
314 SE: Fn(&animation::Transition<O>, EasingStep) -> O + Send + Sync + 'static,
315 {
316 var_easing_with_mixed(self, duration, easing, sampler)
317 }
318}
319
320impl<I: VarValue, O: VarValue, S: WeakVar<I>> WeakVar<O> for WeakMapRef<I, O, S> {
321 type Upgrade = MapRef<I, O, S::Upgrade>;
322
323 fn upgrade(&self) -> Option<Self::Upgrade> {
324 self.source.upgrade().map(|s| MapRef {
325 source: s,
326 map: self.map.clone(),
327 })
328 }
329}
330
331pub struct MapRefBidi<I, O, S> {
333 source: S,
334 map: Arc<dyn Fn(&I) -> &O + Send + Sync>,
335 map_mut: Arc<dyn Fn(&mut I) -> &mut O + Send + Sync>,
336}
337
338pub struct WeakMapRefBidi<I, O, S> {
340 source: S,
341 map: Arc<dyn Fn(&I) -> &O + Send + Sync>,
342 map_mut: Arc<dyn Fn(&mut I) -> &mut O + Send + Sync>,
343}
344
345impl<I: VarValue, O: VarValue, S: Var<I>> MapRefBidi<I, O, S> {
346 pub(super) fn new(source: S, map: Arc<dyn Fn(&I) -> &O + Send + Sync>, map_mut: Arc<dyn Fn(&mut I) -> &mut O + Send + Sync>) -> Self {
347 MapRefBidi { source, map, map_mut }
348 }
349}
350
351impl<I: VarValue, O: VarValue, S: Var<I>> crate::private::Sealed for MapRefBidi<I, O, S> {}
352impl<I: VarValue, O: VarValue, S: WeakVar<I>> crate::private::Sealed for WeakMapRefBidi<I, O, S> {}
353
354impl<I: VarValue, O: VarValue, S: Var<I>> Clone for MapRefBidi<I, O, S> {
355 fn clone(&self) -> Self {
356 Self {
357 source: self.source.clone(),
358 map: self.map.clone(),
359 map_mut: self.map_mut.clone(),
360 }
361 }
362}
363impl<I: VarValue, O: VarValue, S: WeakVar<I>> Clone for WeakMapRefBidi<I, O, S> {
364 fn clone(&self) -> Self {
365 Self {
366 source: self.source.clone(),
367 map: self.map.clone(),
368 map_mut: self.map_mut.clone(),
369 }
370 }
371}
372
373impl<I: VarValue, O: VarValue, S: Var<I>> AnyVar for MapRefBidi<I, O, S> {
374 fn clone_any(&self) -> BoxedAnyVar {
375 Box::new(self.clone())
376 }
377
378 fn as_any(&self) -> &dyn Any {
379 self
380 }
381
382 fn as_unboxed_any(&self) -> &dyn Any {
383 self
384 }
385
386 fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
387 let me: BoxedVar<O> = self;
388 Box::new(me)
389 }
390
391 fn var_type_id(&self) -> TypeId {
392 TypeId::of::<O>()
393 }
394
395 fn get_any(&self) -> Box<dyn AnyVarValue> {
396 Box::new(self.get())
397 }
398
399 fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
400 self.with(|v| read(v))
401 }
402
403 fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
404 self.with_new(|v| read(v)).is_some()
405 }
406
407 fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
408 self.modify(var_set_any(value))
409 }
410
411 fn last_update(&self) -> VarUpdateId {
412 self.source.last_update()
413 }
414
415 fn is_contextual(&self) -> bool {
416 self.source.is_contextual()
417 }
418
419 fn capabilities(&self) -> VarCapability {
420 self.source.capabilities()
421 }
422
423 fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
424 let map = self.map.clone();
425 self.source.hook_any(Box::new(move |args| {
426 if let Some(value) = args.downcast_value() {
427 let value = map(value);
428 pos_modify_action(&AnyVarHookArgs::new(value, args.update(), args.tags()))
429 } else {
430 true
431 }
432 }))
433 }
434
435 fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
436 self.source.hook_animation_stop(handler)
437 }
438
439 fn strong_count(&self) -> usize {
440 self.source.strong_count()
441 }
442
443 fn weak_count(&self) -> usize {
444 self.source.weak_count()
445 }
446
447 fn actual_var_any(&self) -> BoxedAnyVar {
448 Box::new(self.clone().actual_var())
449 }
450
451 fn downgrade_any(&self) -> BoxedAnyWeakVar {
452 Box::new(self.downgrade())
453 }
454
455 fn is_animating(&self) -> bool {
456 self.source.is_animating()
457 }
458
459 fn modify_importance(&self) -> usize {
460 self.source.modify_importance()
461 }
462
463 fn var_ptr(&self) -> VarPtr {
464 self.source.var_ptr()
465 }
466
467 fn get_debug(&self) -> Txt {
468 self.with(var_debug)
469 }
470
471 fn update(&self) -> Result<(), VarIsReadOnlyError> {
472 Var::modify(self, var_update)
473 }
474
475 fn map_debug(&self) -> BoxedVar<Txt> {
476 Var::map(self, var_debug).boxed()
477 }
478}
479impl<I: VarValue, O: VarValue, S: WeakVar<I>> AnyWeakVar for WeakMapRefBidi<I, O, S> {
480 fn clone_any(&self) -> BoxedAnyWeakVar {
481 Box::new(self.clone())
482 }
483
484 fn strong_count(&self) -> usize {
485 self.source.strong_count()
486 }
487
488 fn weak_count(&self) -> usize {
489 self.source.weak_count()
490 }
491
492 fn upgrade_any(&self) -> Option<BoxedAnyVar> {
493 self.upgrade().map(|m| Box::new(m) as _)
494 }
495
496 fn as_any(&self) -> &dyn Any {
497 self
498 }
499}
500
501impl<I: VarValue, O: VarValue, S: Var<I>> IntoVar<O> for MapRefBidi<I, O, S> {
502 type Var = Self;
503
504 fn into_var(self) -> Self::Var {
505 self
506 }
507}
508
509impl<I: VarValue, O: VarValue, S: Var<I>> Var<O> for MapRefBidi<I, O, S> {
510 type ReadOnly = Self;
511
512 type ActualVar = MapRefBidi<I, O, S::ActualVar>;
513
514 type Downgrade = WeakMapRefBidi<I, O, S::Downgrade>;
515
516 type Map<MO: VarValue> = contextualized::ContextualizedVar<MO>;
517 type MapBidi<MO: VarValue> = contextualized::ContextualizedVar<MO>;
518
519 type FlatMap<OF: VarValue, V: Var<OF>> = contextualized::ContextualizedVar<OF>;
520
521 type FilterMap<OF: VarValue> = contextualized::ContextualizedVar<OF>;
522 type FilterMapBidi<OF: VarValue> = contextualized::ContextualizedVar<OF>;
523
524 type MapRef<OM: VarValue> = types::MapRef<O, OM, Self>;
525 type MapRefBidi<OM: VarValue> = types::MapRefBidi<O, OM, Self>;
526
527 type Easing = types::ContextualizedVar<O>;
528
529 fn with<R, F>(&self, read: F) -> R
530 where
531 F: FnOnce(&O) -> R,
532 {
533 self.source.with(|val| {
534 let val = (self.map)(val);
535 read(val)
536 })
537 }
538
539 fn modify<F>(&self, modify: F) -> Result<(), VarIsReadOnlyError>
540 where
541 F: FnOnce(&mut VarModify<O>) + Send + 'static,
542 {
543 let map = self.map.clone();
544 let map_mut = self.map_mut.clone();
545 self.source.modify(move |vm| {
546 let (notify, new_value, update, tags, custom_importance) = {
547 let mut vm = VarModify::new(map(vm.as_ref()));
548 modify(&mut vm);
549 vm.finish()
550 };
551 if let Some(i) = custom_importance {
552 vm.set_modify_importance(i);
553 }
554 if notify {
555 if update {
556 vm.update();
557 }
558 if let Some(nv) = new_value {
559 *map_mut(vm.to_mut()) = nv;
560 }
561 vm.push_tags(tags);
562 }
563 })
564 }
565
566 fn actual_var(self) -> Self::ActualVar {
567 MapRefBidi {
568 source: self.source.actual_var(),
569 map: self.map,
570 map_mut: self.map_mut,
571 }
572 }
573
574 fn downgrade(&self) -> Self::Downgrade {
575 WeakMapRefBidi {
576 source: self.source.downgrade(),
577 map: self.map.clone(),
578 map_mut: self.map_mut.clone(),
579 }
580 }
581
582 fn into_value(self) -> O {
583 self.get()
584 }
585
586 fn read_only(&self) -> Self::ReadOnly {
587 self.clone()
588 }
589
590 fn map<MO, M>(&self, map: M) -> Self::Map<MO>
591 where
592 MO: VarValue,
593 M: FnMut(&O) -> MO + Send + 'static,
594 {
595 var_map_ctx(self, map)
596 }
597
598 fn map_bidi<MO, M, B>(&self, map: M, map_back: B) -> Self::MapBidi<MO>
599 where
600 MO: VarValue,
601 M: FnMut(&O) -> MO + Send + 'static,
602 B: FnMut(&MO) -> O + Send + 'static,
603 {
604 var_map_bidi_ctx(self, map, map_back)
605 }
606
607 fn flat_map<OF, V, M>(&self, map: M) -> Self::FlatMap<OF, V>
608 where
609 OF: VarValue,
610 V: Var<OF>,
611 M: FnMut(&O) -> V + Send + 'static,
612 {
613 var_flat_map_ctx(self, map)
614 }
615
616 fn filter_map<OF, M, IF>(&self, map: M, fallback: IF) -> Self::FilterMap<OF>
617 where
618 OF: VarValue,
619 M: FnMut(&O) -> Option<OF> + Send + 'static,
620 IF: Fn() -> OF + Send + Sync + 'static,
621 {
622 var_filter_map_ctx(self, map, fallback)
623 }
624
625 fn filter_map_bidi<OF, M, B, IF>(&self, map: M, map_back: B, fallback: IF) -> Self::FilterMapBidi<OF>
626 where
627 OF: VarValue,
628 M: FnMut(&O) -> Option<OF> + Send + 'static,
629 B: FnMut(&OF) -> Option<O> + Send + 'static,
630 IF: Fn() -> OF + Send + Sync + 'static,
631 {
632 var_filter_map_bidi_ctx(self, map, map_back, fallback)
633 }
634
635 fn map_ref<OM, M>(&self, map: M) -> Self::MapRef<OM>
636 where
637 OM: VarValue,
638 M: Fn(&O) -> &OM + Send + Sync + 'static,
639 {
640 var_map_ref(self, map)
641 }
642
643 fn map_ref_bidi<OM, M, B>(&self, map: M, map_mut: B) -> Self::MapRefBidi<OM>
644 where
645 OM: VarValue,
646 M: Fn(&O) -> &OM + Send + Sync + 'static,
647 B: Fn(&mut O) -> &mut OM + Send + Sync + 'static,
648 {
649 var_map_ref_bidi(self, map, map_mut)
650 }
651
652 fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
653 where
654 O: Transitionable,
655 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
656 {
657 var_easing_ctx(self, duration, easing)
658 }
659
660 fn easing_with<F, SA>(&self, duration: Duration, easing: F, sampler: SA) -> Self::Easing
661 where
662 O: Transitionable,
663 F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
664 SA: Fn(&animation::Transition<O>, EasingStep) -> O + Send + Sync + 'static,
665 {
666 var_easing_with_ctx(self, duration, easing, sampler)
667 }
668}
669
670impl<I: VarValue, O: VarValue, S: WeakVar<I>> WeakVar<O> for WeakMapRefBidi<I, O, S> {
671 type Upgrade = MapRefBidi<I, O, S::Upgrade>;
672
673 fn upgrade(&self) -> Option<Self::Upgrade> {
674 self.source.upgrade().map(|s| MapRefBidi {
675 source: s,
676 map: self.map.clone(),
677 map_mut: self.map_mut.clone(),
678 })
679 }
680}