vizia_core/binding/
res.rs

1use crate::prelude::*;
2
3#[macro_export]
4/// A macro for implementing the [Res] trait for simple `Copy` types.
5macro_rules! impl_res_simple {
6    ($t:ty) => {
7        impl ResGet<$t> for $t {
8            fn get_ref<'a>(&self, _: &impl DataContext) -> Option<LensValue<$t>> {
9                Some(LensValue::Borrowed(self))
10            }
11
12            fn get(&self, _: &impl DataContext) -> $t {
13                *self
14            }
15        }
16
17        impl Res<$t> for $t {}
18    };
19}
20
21#[macro_export]
22/// A macro for implementing the [Res] trait for `Clone` types.
23macro_rules! impl_res_clone {
24    ($t:ty) => {
25        impl ResGet<$t> for $t {
26            fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, $t>> {
27                Some(LensValue::Borrowed(self))
28            }
29
30            fn get(&self, _: &impl DataContext) -> $t {
31                self.clone()
32            }
33        }
34
35        impl Res<$t> for $t {}
36    };
37}
38
39/// A trait for retrieving the value of a lens.
40pub trait ResGet<T> {
41    /// Returns the value of a lens by reference.
42    fn get_ref<'a>(&'a self, cx: &'a impl DataContext) -> Option<LensValue<'a, T>>;
43    /// returns the value of a lens by value.
44    fn get(&self, _: &impl DataContext) -> T;
45}
46
47/// A trait which allows passing a value or a lens to a view or modifier.
48///
49/// For example, the `Label` view constructor takes a type which implements `Res<T>` where
50/// `T` implements `ToString`. This allows the user to pass a type which implements `ToString`,
51/// such as `String` or `&str`, or a lens to a type which implements `ToString`.
52pub trait Res<T>: ResGet<T> {
53    fn set_or_bind<F>(self, cx: &mut Context, entity: Entity, closure: F)
54    where
55        Self: Sized,
56        F: 'static + Fn(&mut Context, Self),
57    {
58        cx.with_current(entity, |cx| {
59            (closure)(cx, self);
60        });
61    }
62}
63
64impl<L> ResGet<L::Target> for L
65where
66    L: Lens<Target: Clone>,
67{
68    fn get_ref<'a>(&'a self, cx: &'a impl DataContext) -> Option<LensValue<'a, L::Target>> {
69        self.view(
70            cx.data()
71                .unwrap_or_else(|| panic!("Failed to get data from context for lens: {:?}", self)),
72        )
73    }
74
75    fn get(&self, cx: &impl DataContext) -> L::Target {
76        self.get_ref(cx).unwrap().into_owned()
77    }
78}
79
80impl<L> Res<L::Target> for L
81where
82    L: Lens<Target: Data>,
83{
84    fn set_or_bind<F>(self, cx: &mut Context, entity: Entity, closure: F)
85    where
86        F: 'static + Fn(&mut Context, Self),
87    {
88        // cx.with_current(entity, |cx| {
89        Binding::new(cx, self, move |cx, val| {
90            cx.with_current(entity, |cx| {
91                (closure)(cx, val);
92            });
93        });
94        // });
95        // });
96    }
97}
98
99impl_res_simple!(i8);
100impl_res_simple!(i16);
101impl_res_simple!(i32);
102impl_res_simple!(i64);
103impl_res_simple!(i128);
104impl_res_simple!(isize);
105impl_res_simple!(u8);
106impl_res_simple!(u16);
107impl_res_simple!(u32);
108impl_res_simple!(u64);
109impl_res_simple!(u128);
110impl_res_simple!(usize);
111impl_res_simple!(char);
112impl_res_simple!(bool);
113impl_res_simple!(f32);
114impl_res_simple!(f64);
115impl_res_simple!(CursorIcon);
116impl_res_simple!(Overflow);
117impl_res_simple!(LengthValue);
118impl_res_simple!(FontWeight);
119impl_res_simple!(FontWeightKeyword);
120impl_res_simple!(FontSlant);
121impl_res_simple!(CornerShape);
122impl_res_simple!(Angle);
123impl_res_simple!(TextAlign);
124impl_res_simple!(TextOverflow);
125impl_res_simple!(LineClamp);
126impl_res_clone!(Shadow);
127impl_res_clone!(LinearGradientBuilder);
128impl_res_clone!(ShadowBuilder);
129impl_res_simple!(FontVariation);
130impl_res_clone!(Filter);
131impl_res_simple!(Opacity);
132impl_res_simple!(FontWidth);
133impl_res_clone!(Translate);
134impl_res_clone!(Scale);
135impl_res_clone!(Position);
136impl_res_simple!(PointerEvents);
137impl_res_simple!(ButtonVariant);
138impl_res_simple!(AvatarVariant);
139impl_res_clone!(FamilyOwned);
140impl_res_simple!(TextDecorationLine);
141impl_res_clone!(TextStroke);
142impl_res_clone!(TextStrokeStyle);
143impl_res_simple!(Alignment);
144impl_res_simple!(WindowPosition);
145impl_res_simple!(Anchor);
146impl_res_simple!(AnchorTarget);
147impl_res_clone!(std::ops::Range<f32>);
148
149impl<'i> ResGet<FontFamily<'i>> for FontFamily<'i> {
150    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
151        Some(LensValue::Borrowed(self))
152    }
153
154    fn get(&self, _: &impl DataContext) -> Self {
155        self.clone()
156    }
157}
158
159impl<'i> Res<FontFamily<'i>> for FontFamily<'i> {}
160
161impl<'i> ResGet<BackgroundImage<'i>> for BackgroundImage<'i> {
162    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
163        Some(LensValue::Borrowed(self))
164    }
165
166    fn get(&self, _: &impl DataContext) -> Self {
167        self.clone()
168    }
169}
170
171impl<'i> Res<BackgroundImage<'i>> for BackgroundImage<'i> {}
172
173impl<'s> ResGet<&'s str> for &'s str {
174    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
175        Some(LensValue::Borrowed(self))
176    }
177
178    fn get(&self, _: &impl DataContext) -> &'s str {
179        self
180    }
181}
182
183impl<'s> Res<&'s str> for &'s str {}
184
185impl<'s> ResGet<&'s String> for &'s String {
186    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
187        Some(LensValue::Borrowed(self))
188    }
189
190    fn get(&self, _: &impl DataContext) -> Self {
191        self
192    }
193}
194
195impl<'s> Res<&'s String> for &'s String {}
196
197impl ResGet<String> for String {
198    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
199        Some(LensValue::Borrowed(self))
200    }
201
202    fn get(&self, _: &impl DataContext) -> Self {
203        self.clone()
204    }
205}
206
207impl Res<String> for String {}
208
209impl ResGet<Transform> for Transform {
210    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
211        Some(LensValue::Borrowed(self))
212    }
213
214    fn get(&self, _: &impl DataContext) -> Transform {
215        self.clone()
216    }
217}
218
219impl Res<Transform> for Transform {}
220
221impl ResGet<Color> for Color {
222    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
223        Some(LensValue::Borrowed(self))
224    }
225
226    fn get(&self, _: &impl DataContext) -> Color {
227        *self
228    }
229}
230
231impl Res<Color> for Color {}
232
233impl ResGet<LinearGradient> for LinearGradient {
234    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
235        Some(LensValue::Borrowed(self))
236    }
237
238    fn get(&self, _: &impl DataContext) -> LinearGradient {
239        self.clone()
240    }
241}
242
243impl Res<LinearGradient> for LinearGradient {}
244
245impl ResGet<Units> for Units {
246    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
247        Some(LensValue::Borrowed(self))
248    }
249
250    fn get(&self, _: &impl DataContext) -> Units {
251        *self
252    }
253}
254
255impl Res<Units> for Units {}
256
257impl ResGet<Visibility> for Visibility {
258    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
259        Some(LensValue::Borrowed(self))
260    }
261
262    fn get(&self, _: &impl DataContext) -> Visibility {
263        *self
264    }
265}
266
267impl Res<Visibility> for Visibility {}
268
269impl ResGet<Display> for Display {
270    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
271        Some(LensValue::Borrowed(self))
272    }
273
274    fn get(&self, _: &impl DataContext) -> Display {
275        *self
276    }
277}
278
279impl Res<Display> for Display {}
280
281impl ResGet<LayoutType> for LayoutType {
282    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
283        Some(LensValue::Borrowed(self))
284    }
285
286    fn get(&self, _: &impl DataContext) -> LayoutType {
287        *self
288    }
289}
290impl Res<LayoutType> for LayoutType {}
291
292impl ResGet<PositionType> for PositionType {
293    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
294        Some(LensValue::Borrowed(self))
295    }
296
297    fn get(&self, _: &impl DataContext) -> PositionType {
298        *self
299    }
300}
301
302impl Res<PositionType> for PositionType {}
303
304impl<T: Clone + ResGet<T>> ResGet<Option<T>> for Option<T> {
305    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
306        Some(LensValue::Borrowed(self))
307    }
308
309    fn get(&self, _: &impl DataContext) -> Option<T> {
310        self.clone()
311    }
312}
313
314impl<T: Clone + ResGet<T>> Res<Option<T>> for Option<T> {}
315
316impl ResGet<Length> for Length {
317    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
318        Some(LensValue::Borrowed(self))
319    }
320
321    fn get(&self, _: &impl DataContext) -> Self {
322        self.clone()
323    }
324}
325
326impl Res<Length> for Length {}
327
328impl ResGet<LengthOrPercentage> for LengthOrPercentage {
329    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
330        Some(LensValue::Borrowed(self))
331    }
332
333    fn get(&self, _: &impl DataContext) -> Self {
334        self.clone()
335    }
336}
337
338impl Res<LengthOrPercentage> for LengthOrPercentage {}
339
340impl ResGet<RGBA> for RGBA {
341    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
342        Some(LensValue::Borrowed(self))
343    }
344
345    fn get(&self, _: &impl DataContext) -> Self {
346        *self
347    }
348}
349
350impl Res<RGBA> for RGBA {}
351
352impl<T: Clone + ResGet<T>> ResGet<Vec<T>> for Vec<T> {
353    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
354        Some(LensValue::Borrowed(self))
355    }
356
357    fn get(&self, _: &impl DataContext) -> Vec<T> {
358        self.clone()
359    }
360}
361
362impl<T: Clone + ResGet<T>> Res<Vec<T>> for Vec<T> {}
363
364impl<T: Clone + ResGet<T>, const N: usize> ResGet<[T; N]> for [T; N] {
365    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
366        Some(LensValue::Borrowed(self))
367    }
368
369    fn get(&self, _: &impl DataContext) -> Self {
370        self.clone()
371    }
372}
373
374impl<T: Clone + ResGet<T>, const N: usize> Res<[T; N]> for [T; N] {}
375
376impl<T1: Clone, T2: Clone> ResGet<(T1, T2)> for (T1, T2) {
377    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
378        Some(LensValue::Borrowed(self))
379    }
380
381    fn get(&self, _cx: &impl DataContext) -> (T1, T2) {
382        self.clone()
383    }
384}
385
386impl<T1: Clone, T2: Clone> Res<(T1, T2)> for (T1, T2) {}
387
388impl<T1: Clone, T2: Clone, T3: Clone> ResGet<(T1, T2, T3)> for (T1, T2, T3) {
389    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
390        Some(LensValue::Borrowed(self))
391    }
392
393    fn get(&self, _cx: &impl DataContext) -> (T1, T2, T3) {
394        self.clone()
395    }
396}
397
398impl<T1: Clone, T2: Clone, T3: Clone> Res<(T1, T2, T3)> for (T1, T2, T3) {}
399
400impl<T1: Clone, T2: Clone, T3: Clone, T4: Clone> ResGet<(T1, T2, T3, T4)> for (T1, T2, T3, T4) {
401    fn get_ref<'a>(&'a self, _: &'a impl DataContext) -> Option<LensValue<'a, Self>> {
402        Some(LensValue::Borrowed(self))
403    }
404
405    fn get(&self, _cx: &impl DataContext) -> (T1, T2, T3, T4) {
406        self.clone()
407    }
408}
409
410impl<T1: Clone, T2: Clone, T3: Clone, T4: Clone> Res<(T1, T2, T3, T4)> for (T1, T2, T3, T4) {}