zng_var/
boxed.rs

1use std::any::TypeId;
2
3use super::*;
4
5/// Represents a [`Var<T>`] boxed.
6pub type BoxedVar<T> = Box<dyn VarBoxed<T>>;
7
8/// Represents a weak reference to a [`BoxedVar<T>`].
9pub type BoxedWeakVar<T> = Box<dyn WeakVarBoxed<T>>;
10
11/// Represents a type erased boxed var.
12pub type BoxedAnyVar = Box<dyn AnyVar>;
13
14/// Represents a weak reference to a [`BoxedAnyVar`].
15pub type BoxedAnyWeakVar = Box<dyn AnyWeakVar>;
16
17impl<T: VarValue> Clone for BoxedWeakVar<T> {
18    fn clone(&self) -> Self {
19        self.clone_boxed()
20    }
21}
22
23impl Clone for BoxedAnyVar {
24    fn clone(&self) -> Self {
25        self.clone_any()
26    }
27}
28
29impl Clone for BoxedAnyWeakVar {
30    fn clone(&self) -> Self {
31        self.clone_any()
32    }
33}
34
35impl crate::private::Sealed for Box<dyn AnyVar> {}
36
37impl AnyVar for Box<dyn AnyVar> {
38    fn clone_any(&self) -> BoxedAnyVar {
39        (**self).clone_any()
40    }
41
42    fn as_any(&self) -> &dyn Any {
43        (**self).as_any()
44    }
45
46    fn as_unboxed_any(&self) -> &dyn Any {
47        (**self).as_unboxed_any()
48    }
49
50    fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
51        self
52    }
53
54    fn var_type_id(&self) -> TypeId {
55        (**self).var_type_id()
56    }
57
58    fn get_any(&self) -> Box<dyn AnyVarValue> {
59        (**self).get_any()
60    }
61
62    fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
63        (**self).with_any(read)
64    }
65
66    fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
67        (**self).with_new_any(read)
68    }
69
70    fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
71        (**self).set_any(value)
72    }
73
74    fn last_update(&self) -> VarUpdateId {
75        (**self).last_update()
76    }
77
78    fn is_contextual(&self) -> bool {
79        (**self).is_contextual()
80    }
81
82    fn capabilities(&self) -> VarCapability {
83        (**self).capabilities()
84    }
85
86    fn is_animating(&self) -> bool {
87        (**self).is_animating()
88    }
89
90    fn modify_importance(&self) -> usize {
91        (**self).modify_importance()
92    }
93
94    fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
95        (**self).hook_any(pos_modify_action)
96    }
97
98    fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
99        (**self).hook_animation_stop(handler)
100    }
101
102    fn strong_count(&self) -> usize {
103        (**self).strong_count()
104    }
105
106    fn weak_count(&self) -> usize {
107        (**self).weak_count()
108    }
109
110    fn actual_var_any(&self) -> BoxedAnyVar {
111        (**self).actual_var_any()
112    }
113
114    fn downgrade_any(&self) -> BoxedAnyWeakVar {
115        (**self).downgrade_any()
116    }
117
118    fn var_ptr(&self) -> VarPtr {
119        (**self).var_ptr()
120    }
121
122    fn get_debug(&self) -> Txt {
123        (**self).get_debug()
124    }
125
126    fn update(&self) -> Result<(), VarIsReadOnlyError> {
127        (**self).update()
128    }
129
130    fn map_debug(&self) -> BoxedVar<Txt> {
131        (**self).map_debug()
132    }
133}
134
135#[doc(hidden)]
136pub trait VarBoxed<T: VarValue>: AnyVar {
137    fn clone_boxed(&self) -> BoxedVar<T>;
138    fn with_boxed(&self, read: &mut dyn FnMut(&T));
139    fn modify_boxed(&self, modify: Box<dyn FnOnce(&mut VarModify<T>) + Send>) -> Result<(), VarIsReadOnlyError>;
140    fn actual_var_boxed(self: Box<Self>) -> BoxedVar<T>;
141    fn downgrade_boxed(&self) -> BoxedWeakVar<T>;
142    fn read_only_boxed(&self) -> BoxedVar<T>;
143    fn boxed_any_boxed(self: Box<Self>) -> BoxedAnyVar;
144}
145impl<T: VarValue, V: Var<T>> VarBoxed<T> for V {
146    fn clone_boxed(&self) -> BoxedVar<T> {
147        self.clone().boxed()
148    }
149
150    fn with_boxed(&self, read: &mut dyn FnMut(&T)) {
151        self.with(read)
152    }
153
154    fn modify_boxed(&self, modify: Box<dyn FnOnce(&mut VarModify<T>) + Send>) -> Result<(), VarIsReadOnlyError> {
155        self.modify(modify)
156    }
157
158    fn actual_var_boxed(self: Box<Self>) -> BoxedVar<T> {
159        (*self).actual_var().boxed()
160    }
161
162    fn downgrade_boxed(&self) -> BoxedWeakVar<T> {
163        self.downgrade().boxed()
164    }
165
166    fn read_only_boxed(&self) -> BoxedVar<T> {
167        self.read_only().boxed()
168    }
169
170    fn boxed_any_boxed(self: Box<Self>) -> BoxedAnyVar {
171        self
172    }
173}
174
175#[doc(hidden)]
176pub trait WeakVarBoxed<T: VarValue>: AnyWeakVar {
177    fn clone_boxed(&self) -> BoxedWeakVar<T>;
178    fn upgrade_boxed(&self) -> Option<BoxedVar<T>>;
179}
180impl<T: VarValue, W: WeakVar<T>> WeakVarBoxed<T> for W {
181    fn clone_boxed(&self) -> BoxedWeakVar<T> {
182        self.clone().boxed()
183    }
184
185    fn upgrade_boxed(&self) -> Option<BoxedVar<T>> {
186        self.upgrade().map(Var::boxed)
187    }
188}
189
190impl<T: VarValue> crate::private::Sealed for BoxedWeakVar<T> {}
191
192impl<T: VarValue> AnyWeakVar for BoxedWeakVar<T> {
193    fn clone_any(&self) -> BoxedAnyWeakVar {
194        (**self).clone_any()
195    }
196
197    fn strong_count(&self) -> usize {
198        (**self).strong_count()
199    }
200
201    fn weak_count(&self) -> usize {
202        (**self).weak_count()
203    }
204
205    fn upgrade_any(&self) -> Option<BoxedAnyVar> {
206        (**self).upgrade_any()
207    }
208
209    fn as_any(&self) -> &dyn Any {
210        self
211    }
212}
213impl<T: VarValue> WeakVar<T> for BoxedWeakVar<T> {
214    type Upgrade = BoxedVar<T>;
215
216    fn upgrade(&self) -> Option<Self::Upgrade> {
217        (**self).upgrade_boxed()
218    }
219}
220
221impl<T: VarValue> crate::private::Sealed for BoxedVar<T> {}
222
223impl<T: VarValue> Clone for BoxedVar<T> {
224    fn clone(&self) -> Self {
225        (**self).clone_boxed()
226    }
227}
228
229impl<T: VarValue> AnyVar for BoxedVar<T> {
230    fn clone_any(&self) -> BoxedAnyVar {
231        (**self).clone_any()
232    }
233
234    fn as_any(&self) -> &dyn Any {
235        self
236    }
237
238    fn as_unboxed_any(&self) -> &dyn Any {
239        (**self).as_unboxed_any()
240    }
241
242    fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
243        self
244    }
245
246    fn var_type_id(&self) -> TypeId {
247        (**self).var_type_id()
248    }
249
250    fn get_any(&self) -> Box<dyn AnyVarValue> {
251        (**self).get_any()
252    }
253
254    fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
255        (**self).with_any(read)
256    }
257
258    fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
259        (**self).with_new_any(read)
260    }
261
262    fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
263        (**self).set_any(value)
264    }
265
266    fn last_update(&self) -> VarUpdateId {
267        (**self).last_update()
268    }
269
270    fn is_contextual(&self) -> bool {
271        (**self).is_contextual()
272    }
273
274    fn capabilities(&self) -> VarCapability {
275        (**self).capabilities()
276    }
277
278    fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
279        (**self).hook_any(pos_modify_action)
280    }
281
282    fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
283        (**self).hook_animation_stop(handler)
284    }
285
286    fn strong_count(&self) -> usize {
287        (**self).strong_count()
288    }
289
290    fn weak_count(&self) -> usize {
291        (**self).weak_count()
292    }
293
294    fn actual_var_any(&self) -> BoxedAnyVar {
295        (**self).actual_var_any()
296    }
297
298    fn downgrade_any(&self) -> BoxedAnyWeakVar {
299        (**self).downgrade_any()
300    }
301
302    fn is_animating(&self) -> bool {
303        (**self).is_animating()
304    }
305
306    fn modify_importance(&self) -> usize {
307        (**self).modify_importance()
308    }
309
310    fn var_ptr(&self) -> VarPtr {
311        (**self).var_ptr()
312    }
313
314    fn get_debug(&self) -> Txt {
315        (**self).get_debug()
316    }
317
318    fn update(&self) -> Result<(), VarIsReadOnlyError> {
319        (**self).update()
320    }
321
322    fn map_debug(&self) -> BoxedVar<Txt> {
323        (**self).map_debug()
324    }
325}
326
327impl<T: VarValue> IntoVar<T> for BoxedVar<T> {
328    type Var = Self;
329
330    fn into_var(self) -> Self::Var {
331        self
332    }
333}
334
335impl<T: VarValue> Var<T> for BoxedVar<T> {
336    type ReadOnly = BoxedVar<T>;
337
338    type ActualVar = BoxedVar<T>;
339
340    type Downgrade = BoxedWeakVar<T>;
341
342    type Map<O: VarValue> = BoxedVar<O>;
343    type MapBidi<O: VarValue> = BoxedVar<O>;
344
345    type FlatMap<O: VarValue, V: Var<O>> = BoxedVar<O>;
346
347    type FilterMap<O: VarValue> = BoxedVar<O>;
348    type FilterMapBidi<O: VarValue> = BoxedVar<O>;
349
350    type MapRef<O: VarValue> = BoxedVar<O>;
351    type MapRefBidi<O: VarValue> = BoxedVar<O>;
352
353    type Easing = BoxedVar<T>;
354
355    fn with<R, F>(&self, read: F) -> R
356    where
357        F: FnOnce(&T) -> R,
358    {
359        #[cfg(feature = "dyn_closure")]
360        let read: Box<dyn FnOnce(&T) -> R> = Box::new(read);
361        boxed_var_with(self, read)
362    }
363
364    fn modify<F>(&self, modify: F) -> Result<(), VarIsReadOnlyError>
365    where
366        F: FnOnce(&mut VarModify<T>) + Send + 'static,
367    {
368        let modify = Box::new(modify);
369        (**self).modify_boxed(modify)
370    }
371
372    fn boxed(self) -> BoxedVar<T> {
373        self
374    }
375
376    fn boxed_any(self) -> BoxedAnyVar
377    where
378        Self: Sized,
379    {
380        // fix after https://github.com/rust-lang/rust/issues/65991
381        self.clone_any()
382    }
383
384    fn actual_var(self) -> BoxedVar<T> {
385        self.actual_var_boxed()
386    }
387
388    fn downgrade(&self) -> BoxedWeakVar<T> {
389        (**self).downgrade_boxed()
390    }
391
392    fn into_value(self) -> T {
393        self.get()
394    }
395
396    fn read_only(&self) -> Self::ReadOnly {
397        if self.capabilities().is_always_read_only() {
398            self.clone()
399        } else {
400            (**self).read_only_boxed()
401        }
402    }
403
404    fn map<O, M>(&self, map: M) -> Self::Map<O>
405    where
406        O: VarValue,
407        M: FnMut(&T) -> O + Send + 'static,
408    {
409        var_map_mixed(self, map)
410    }
411
412    fn map_bidi<O, M, B>(&self, map: M, map_back: B) -> Self::MapBidi<O>
413    where
414        O: VarValue,
415        M: FnMut(&T) -> O + Send + 'static,
416        B: FnMut(&O) -> T + Send + 'static,
417    {
418        var_map_bidi_mixed(self, map, map_back)
419    }
420
421    fn flat_map<O, V, M>(&self, map: M) -> Self::FlatMap<O, V>
422    where
423        O: VarValue,
424        V: Var<O>,
425        M: FnMut(&T) -> V + Send + 'static,
426    {
427        var_flat_map_mixed(self, map)
428    }
429
430    fn filter_map<O, M, I>(&self, map: M, fallback: I) -> Self::FilterMap<O>
431    where
432        O: VarValue,
433        M: FnMut(&T) -> Option<O> + Send + 'static,
434        I: Fn() -> O + Send + Sync + 'static,
435    {
436        var_filter_map_mixed(self, map, fallback)
437    }
438
439    fn filter_map_bidi<O, M, B, I>(&self, map: M, map_back: B, fallback: I) -> Self::FilterMapBidi<O>
440    where
441        O: VarValue,
442        M: FnMut(&T) -> Option<O> + Send + 'static,
443        B: FnMut(&O) -> Option<T> + Send + 'static,
444        I: Fn() -> O + Send + Sync + 'static,
445    {
446        var_filter_map_bidi_mixed(self, map, map_back, fallback)
447    }
448
449    fn map_ref<O, M>(&self, map: M) -> Self::MapRef<O>
450    where
451        O: VarValue,
452        M: Fn(&T) -> &O + Send + Sync + 'static,
453    {
454        var_map_ref(self, map).boxed()
455    }
456
457    fn map_ref_bidi<O, M, B>(&self, map: M, map_mut: B) -> Self::MapRefBidi<O>
458    where
459        O: VarValue,
460        M: Fn(&T) -> &O + Send + Sync + 'static,
461        B: Fn(&mut T) -> &mut O + Send + Sync + 'static,
462    {
463        var_map_ref_bidi(self, map, map_mut).boxed()
464    }
465
466    fn easing<F>(&self, duration: Duration, easing: F) -> Self::Easing
467    where
468        T: Transitionable,
469        F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
470    {
471        var_easing_mixed(self, duration, easing)
472    }
473
474    fn easing_with<F, S>(&self, duration: Duration, easing: F, sampler: S) -> Self::Easing
475    where
476        T: Transitionable,
477        F: Fn(EasingTime) -> EasingStep + Send + Sync + 'static,
478        S: Fn(&animation::Transition<T>, EasingStep) -> T + Send + Sync + 'static,
479    {
480        var_easing_with_mixed(self, duration, easing, sampler)
481    }
482}
483
484fn boxed_var_with<T: VarValue, R, F>(var: &BoxedVar<T>, read: F) -> R
485where
486    F: FnOnce(&T) -> R,
487{
488    let mut read = Some(read);
489    let mut result = None;
490    (**var).with_boxed(&mut |var_value| {
491        let read = read.take().unwrap();
492        result = Some(read(var_value));
493    });
494    result.take().unwrap()
495}