vizia_core/binding/
data.rs

1use std::{ptr, rc::Rc, sync::Arc};
2
3use chrono::{NaiveDate, NaiveTime};
4
5use crate::prelude::*;
6
7/// A trait for fast comparisons of data. Implemented by any type which can be bound to,
8/// i.e. can be cached and compared against previous versions.
9pub trait Data: 'static + Clone {
10    /// A method which determines whether two pieces of data are the same.
11    fn same(&self, other: &Self) -> bool;
12}
13
14macro_rules! impl_data_simple {
15    ($t:ty) => {
16        impl Data for $t {
17            fn same(&self, other: &Self) -> bool {
18                self == other
19            }
20        }
21    };
22}
23
24impl_data_simple!(i8);
25impl_data_simple!(i16);
26impl_data_simple!(i32);
27impl_data_simple!(i64);
28impl_data_simple!(i128);
29impl_data_simple!(isize);
30impl_data_simple!(u8);
31impl_data_simple!(u16);
32impl_data_simple!(u32);
33impl_data_simple!(u64);
34impl_data_simple!(u128);
35impl_data_simple!(usize);
36impl_data_simple!(char);
37impl_data_simple!(bool);
38impl_data_simple!(std::num::NonZeroI8);
39impl_data_simple!(std::num::NonZeroI16);
40impl_data_simple!(std::num::NonZeroI32);
41impl_data_simple!(std::num::NonZeroI64);
42impl_data_simple!(std::num::NonZeroI128);
43impl_data_simple!(std::num::NonZeroIsize);
44impl_data_simple!(std::num::NonZeroU8);
45impl_data_simple!(std::num::NonZeroU16);
46impl_data_simple!(std::num::NonZeroU32);
47impl_data_simple!(std::num::NonZeroU64);
48impl_data_simple!(std::num::NonZeroU128);
49impl_data_simple!(std::num::NonZeroUsize);
50impl_data_simple!(std::time::SystemTime);
51impl_data_simple!(Instant);
52impl_data_simple!(Duration);
53impl_data_simple!(std::io::ErrorKind);
54impl_data_simple!(std::net::Ipv4Addr);
55impl_data_simple!(std::net::Ipv6Addr);
56impl_data_simple!(std::net::SocketAddrV4);
57impl_data_simple!(std::net::SocketAddrV6);
58impl_data_simple!(std::net::IpAddr);
59impl_data_simple!(std::net::SocketAddr);
60impl_data_simple!(std::ops::RangeFull);
61impl_data_simple!(std::path::PathBuf);
62impl_data_simple!(LanguageIdentifier);
63impl_data_simple!(Transform);
64impl_data_simple!(Translate);
65impl_data_simple!(Display);
66impl_data_simple!(Visibility);
67impl_data_simple!(NaiveDate);
68impl_data_simple!(NaiveTime);
69impl_data_simple!(Angle);
70impl_data_simple!(String);
71impl_data_simple!(Entity);
72impl_data_simple!(Localized);
73impl_data_simple!(Length);
74impl_data_simple!(KeyChord);
75impl_data_simple!(FamilyOwned);
76impl_data_simple!(FontWeight);
77impl_data_simple!(TextAlign);
78impl_data_simple!(LengthOrPercentage);
79impl_data_simple!(CornerShape);
80impl_data_simple!(Shadow);
81impl_data_simple!(TextDecorationLine);
82
83impl Data for &'static str {
84    fn same(&self, other: &Self) -> bool {
85        ptr::eq(*self, *other)
86    }
87}
88
89impl Data for f32 {
90    fn same(&self, other: &Self) -> bool {
91        self.to_bits() == other.to_bits()
92    }
93}
94
95impl Data for f64 {
96    fn same(&self, other: &Self) -> bool {
97        self.to_bits() == other.to_bits()
98    }
99}
100
101impl<T: ?Sized + 'static> Data for Arc<T> {
102    fn same(&self, other: &Self) -> bool {
103        Arc::ptr_eq(self, other)
104    }
105}
106
107impl<T: ?Sized + 'static> Data for std::sync::Weak<T> {
108    fn same(&self, other: &Self) -> bool {
109        std::sync::Weak::ptr_eq(self, other)
110    }
111}
112
113impl<T: ?Sized + 'static> Data for Rc<T> {
114    fn same(&self, other: &Self) -> bool {
115        Rc::ptr_eq(self, other)
116    }
117}
118
119impl<T: ?Sized + 'static> Data for std::rc::Weak<T> {
120    fn same(&self, other: &Self) -> bool {
121        std::rc::Weak::ptr_eq(self, other)
122    }
123}
124
125impl<T: Data> Data for Option<T> {
126    fn same(&self, other: &Self) -> bool {
127        match (self, other) {
128            (Some(a), Some(b)) => a.same(b),
129            (None, None) => true,
130            _ => false,
131        }
132    }
133}
134
135impl<T: Data, U: Data> Data for Result<T, U> {
136    fn same(&self, other: &Self) -> bool {
137        match (self, other) {
138            (Ok(a), Ok(b)) => a.same(b),
139            (Err(a), Err(b)) => a.same(b),
140            _ => false,
141        }
142    }
143}
144
145impl Data for () {
146    fn same(&self, _other: &Self) -> bool {
147        true
148    }
149}
150
151impl<T0: Data> Data for (T0,) {
152    fn same(&self, other: &Self) -> bool {
153        self.0.same(&other.0)
154    }
155}
156
157impl<T0: Data, T1: Data> Data for (T0, T1) {
158    fn same(&self, other: &Self) -> bool {
159        self.0.same(&other.0) && self.1.same(&other.1)
160    }
161}
162
163impl<T0: Data, T1: Data, T2: Data> Data for (T0, T1, T2) {
164    fn same(&self, other: &Self) -> bool {
165        self.0.same(&other.0) && self.1.same(&other.1) && self.2.same(&other.2)
166    }
167}
168
169impl<T0: Data, T1: Data, T2: Data, T3: Data> Data for (T0, T1, T2, T3) {
170    fn same(&self, other: &Self) -> bool {
171        self.0.same(&other.0)
172            && self.1.same(&other.1)
173            && self.2.same(&other.2)
174            && self.3.same(&other.3)
175    }
176}
177
178impl<T0: Data, T1: Data, T2: Data, T3: Data, T4: Data> Data for (T0, T1, T2, T3, T4) {
179    fn same(&self, other: &Self) -> bool {
180        self.0.same(&other.0)
181            && self.1.same(&other.1)
182            && self.2.same(&other.2)
183            && self.3.same(&other.3)
184            && self.4.same(&other.4)
185    }
186}
187
188impl<T0: Data, T1: Data, T2: Data, T3: Data, T4: Data, T5: Data> Data for (T0, T1, T2, T3, T4, T5) {
189    fn same(&self, other: &Self) -> bool {
190        self.0.same(&other.0)
191            && self.1.same(&other.1)
192            && self.2.same(&other.2)
193            && self.3.same(&other.3)
194            && self.4.same(&other.4)
195            && self.5.same(&other.5)
196    }
197}
198
199impl<T: 'static + ?Sized> Data for std::marker::PhantomData<T> {
200    fn same(&self, _other: &Self) -> bool {
201        // zero-sized types
202        true
203    }
204}
205
206impl<T: 'static> Data for std::mem::Discriminant<T> {
207    fn same(&self, other: &Self) -> bool {
208        *self == *other
209    }
210}
211
212impl<T: 'static + Data> Data for std::mem::ManuallyDrop<T> {
213    fn same(&self, other: &Self) -> bool {
214        (**self).same(&**other)
215    }
216}
217
218impl<T: Data> Data for std::num::Wrapping<T> {
219    fn same(&self, other: &Self) -> bool {
220        self.0.same(&other.0)
221    }
222}
223
224impl<T: Data> Data for std::ops::Range<T> {
225    fn same(&self, other: &Self) -> bool {
226        self.start.same(&other.start) && self.end.same(&other.end)
227    }
228}
229
230impl<T: Data> Data for std::ops::RangeFrom<T> {
231    fn same(&self, other: &Self) -> bool {
232        self.start.same(&other.start)
233    }
234}
235
236impl<T: Data> Data for std::ops::RangeInclusive<T> {
237    fn same(&self, other: &Self) -> bool {
238        self.start().same(other.start()) && self.end().same(other.end())
239    }
240}
241
242impl<T: Data> Data for std::ops::RangeTo<T> {
243    fn same(&self, other: &Self) -> bool {
244        self.end.same(&other.end)
245    }
246}
247
248impl<T: Data> Data for std::ops::RangeToInclusive<T> {
249    fn same(&self, other: &Self) -> bool {
250        self.end.same(&other.end)
251    }
252}
253
254impl<T: Data> Data for std::ops::Bound<T> {
255    fn same(&self, other: &Self) -> bool {
256        use std::ops::Bound::*;
257        match (self, other) {
258            (Included(t1), Included(t2)) if t1.same(t2) => true,
259            (Excluded(t1), Excluded(t2)) if t1.same(t2) => true,
260            (Unbounded, Unbounded) => true,
261            _ => false,
262        }
263    }
264}
265
266impl<T: Data> Data for Vec<T> {
267    fn same(&self, other: &Self) -> bool {
268        if self.len() != other.len() {
269            return false;
270        }
271
272        for (a, b) in self.iter().zip(other.iter()) {
273            if !a.same(b) {
274                return false;
275            }
276        }
277
278        true
279    }
280}
281
282impl<T: Data> Data for &'static [T] {
283    fn same(&self, other: &Self) -> bool {
284        if self.len() != other.len() {
285            return false;
286        }
287
288        for (a, b) in self.iter().zip(other.iter()) {
289            if !a.same(b) {
290                return false;
291            }
292        }
293
294        true
295    }
296}
297
298impl<T: std::hash::Hash + Eq + Data> Data for std::collections::HashSet<T> {
299    fn same(&self, other: &Self) -> bool {
300        if self.len() != other.len() {
301            return false;
302        }
303
304        self.iter().zip(other.iter()).all(|(a, b)| a.same(b))
305    }
306}
307
308impl<T: std::hash::Hash + Eq + Data, V: Data> Data for std::collections::HashMap<T, V> {
309    fn same(&self, other: &Self) -> bool {
310        if self.len() != other.len() {
311            return false;
312        }
313
314        self.iter().zip(other.iter()).all(|(a, b)| a.0.same(b.0) && a.1.same(b.1))
315    }
316}
317
318impl Data for morphorm::Units {
319    fn same(&self, other: &Self) -> bool {
320        *self == *other
321    }
322}
323
324impl Data for morphorm::LayoutType {
325    fn same(&self, other: &Self) -> bool {
326        *self == *other
327    }
328}
329
330impl Data for morphorm::PositionType {
331    fn same(&self, other: &Self) -> bool {
332        *self == *other
333    }
334}
335
336impl Data for Color {
337    fn same(&self, other: &Self) -> bool {
338        *self == *other
339    }
340}