1use std::ptr;
18use std::rc::Rc;
19use std::sync::Arc;
20
21use crate::kurbo::{self, ParamCurve};
22use crate::piet;
23use crate::shell::Scale;
24
25pub use druid_derive::Data;
26use piet::ImageBuf;
27
28pub trait Data: Clone + 'static {
108 fn same(&self, other: &Self) -> bool;
120 }
122
123macro_rules! impl_data_simple {
128 ($t:ty) => {
129 impl Data for $t {
130 fn same(&self, other: &Self) -> bool {
131 self == other
132 }
133 }
134 };
135}
136
137impl_data_simple!(i8);
140impl_data_simple!(i16);
141impl_data_simple!(i32);
142impl_data_simple!(i64);
143impl_data_simple!(i128);
144impl_data_simple!(isize);
145impl_data_simple!(u8);
146impl_data_simple!(u16);
147impl_data_simple!(u32);
148impl_data_simple!(u64);
149impl_data_simple!(u128);
150impl_data_simple!(usize);
151impl_data_simple!(char);
152impl_data_simple!(bool);
153impl_data_simple!(std::num::NonZeroI8);
154impl_data_simple!(std::num::NonZeroI16);
155impl_data_simple!(std::num::NonZeroI32);
156impl_data_simple!(std::num::NonZeroI64);
157impl_data_simple!(std::num::NonZeroI128);
158impl_data_simple!(std::num::NonZeroIsize);
159impl_data_simple!(std::num::NonZeroU8);
160impl_data_simple!(std::num::NonZeroU16);
161impl_data_simple!(std::num::NonZeroU32);
162impl_data_simple!(std::num::NonZeroU64);
163impl_data_simple!(std::num::NonZeroU128);
164impl_data_simple!(std::num::NonZeroUsize);
165impl_data_simple!(std::time::SystemTime);
166impl_data_simple!(std::time::Instant);
167impl_data_simple!(std::time::Duration);
168impl_data_simple!(std::io::ErrorKind);
169impl_data_simple!(std::net::Ipv4Addr);
170impl_data_simple!(std::net::Ipv6Addr);
171impl_data_simple!(std::net::SocketAddrV4);
172impl_data_simple!(std::net::SocketAddrV6);
173impl_data_simple!(std::net::IpAddr);
174impl_data_simple!(std::net::SocketAddr);
175impl_data_simple!(std::ops::RangeFull);
176impl_data_simple!(druid::piet::InterpolationMode);
177#[cfg(feature = "chrono")]
178impl_data_simple!(chrono::Duration);
179#[cfg(feature = "chrono")]
180impl_data_simple!(chrono::naive::IsoWeek);
181#[cfg(feature = "chrono")]
182impl_data_simple!(chrono::naive::NaiveDate);
183#[cfg(feature = "chrono")]
184impl_data_simple!(chrono::naive::NaiveDateTime);
185#[cfg(feature = "chrono")]
186impl_data_simple!(chrono::naive::NaiveTime);
187
188impl_data_simple!(String);
190
191impl Data for &'static str {
192 fn same(&self, other: &Self) -> bool {
193 ptr::eq(*self, *other)
194 }
195}
196
197impl Data for f32 {
198 fn same(&self, other: &Self) -> bool {
199 self.to_bits() == other.to_bits()
200 }
201}
202
203impl Data for f64 {
204 fn same(&self, other: &Self) -> bool {
205 self.to_bits() == other.to_bits()
206 }
207}
208
209impl<T: ?Sized + 'static> Data for Arc<T> {
211 fn same(&self, other: &Self) -> bool {
212 Arc::ptr_eq(self, other)
213 }
214}
215
216impl<T: ?Sized + 'static> Data for std::sync::Weak<T> {
217 fn same(&self, other: &Self) -> bool {
218 std::sync::Weak::ptr_eq(self, other)
219 }
220}
221
222impl<T: ?Sized + 'static> Data for Rc<T> {
223 fn same(&self, other: &Self) -> bool {
224 Rc::ptr_eq(self, other)
225 }
226}
227
228impl<T: ?Sized + 'static> Data for std::rc::Weak<T> {
229 fn same(&self, other: &Self) -> bool {
230 std::rc::Weak::ptr_eq(self, other)
231 }
232}
233
234impl<T: Data> Data for Option<T> {
235 fn same(&self, other: &Self) -> bool {
236 match (self, other) {
237 (Some(a), Some(b)) => a.same(b),
238 (None, None) => true,
239 _ => false,
240 }
241 }
242}
243
244impl<T: Data, U: Data> Data for Result<T, U> {
245 fn same(&self, other: &Self) -> bool {
246 match (self, other) {
247 (Ok(a), Ok(b)) => a.same(b),
248 (Err(a), Err(b)) => a.same(b),
249 _ => false,
250 }
251 }
252}
253
254impl Data for () {
255 fn same(&self, _other: &Self) -> bool {
256 true
257 }
258}
259
260impl<T0: Data> Data for (T0,) {
261 fn same(&self, other: &Self) -> bool {
262 self.0.same(&other.0)
263 }
264}
265
266impl<T0: Data, T1: Data> Data for (T0, T1) {
267 fn same(&self, other: &Self) -> bool {
268 self.0.same(&other.0) && self.1.same(&other.1)
269 }
270}
271
272impl<T0: Data, T1: Data, T2: Data> Data for (T0, T1, T2) {
273 fn same(&self, other: &Self) -> bool {
274 self.0.same(&other.0) && self.1.same(&other.1) && self.2.same(&other.2)
275 }
276}
277
278impl<T0: Data, T1: Data, T2: Data, T3: Data> Data for (T0, T1, T2, T3) {
279 fn same(&self, other: &Self) -> bool {
280 self.0.same(&other.0)
281 && self.1.same(&other.1)
282 && self.2.same(&other.2)
283 && self.3.same(&other.3)
284 }
285}
286
287impl<T0: Data, T1: Data, T2: Data, T3: Data, T4: Data> Data for (T0, T1, T2, T3, T4) {
288 fn same(&self, other: &Self) -> bool {
289 self.0.same(&other.0)
290 && self.1.same(&other.1)
291 && self.2.same(&other.2)
292 && self.3.same(&other.3)
293 && self.4.same(&other.4)
294 }
295}
296
297impl<T0: Data, T1: Data, T2: Data, T3: Data, T4: Data, T5: Data> Data for (T0, T1, T2, T3, T4, T5) {
298 fn same(&self, other: &Self) -> bool {
299 self.0.same(&other.0)
300 && self.1.same(&other.1)
301 && self.2.same(&other.2)
302 && self.3.same(&other.3)
303 && self.4.same(&other.4)
304 && self.5.same(&other.5)
305 }
306}
307
308impl<T: 'static + ?Sized> Data for std::marker::PhantomData<T> {
309 fn same(&self, _other: &Self) -> bool {
310 true
312 }
313}
314
315impl<T: 'static> Data for std::mem::Discriminant<T> {
316 fn same(&self, other: &Self) -> bool {
317 *self == *other
318 }
319}
320
321impl<T: 'static + ?Sized + Data> Data for std::mem::ManuallyDrop<T> {
322 fn same(&self, other: &Self) -> bool {
323 (**self).same(&**other)
324 }
325}
326
327impl<T: Data> Data for std::num::Wrapping<T> {
328 fn same(&self, other: &Self) -> bool {
329 self.0.same(&other.0)
330 }
331}
332
333impl<T: Data> Data for std::ops::Range<T> {
334 fn same(&self, other: &Self) -> bool {
335 self.start.same(&other.start) && self.end.same(&other.end)
336 }
337}
338
339impl<T: Data> Data for std::ops::RangeFrom<T> {
340 fn same(&self, other: &Self) -> bool {
341 self.start.same(&other.start)
342 }
343}
344
345impl<T: Data> Data for std::ops::RangeInclusive<T> {
346 fn same(&self, other: &Self) -> bool {
347 self.start().same(other.start()) && self.end().same(other.end())
348 }
349}
350
351impl<T: Data> Data for std::ops::RangeTo<T> {
352 fn same(&self, other: &Self) -> bool {
353 self.end.same(&other.end)
354 }
355}
356
357impl<T: Data> Data for std::ops::RangeToInclusive<T> {
358 fn same(&self, other: &Self) -> bool {
359 self.end.same(&other.end)
360 }
361}
362
363impl<T: Data> Data for std::ops::Bound<T> {
364 fn same(&self, other: &Self) -> bool {
365 use std::ops::Bound::*;
366 match (self, other) {
367 (Included(t1), Included(t2)) if t1.same(t2) => true,
368 (Excluded(t1), Excluded(t2)) if t1.same(t2) => true,
369 (Unbounded, Unbounded) => true,
370 _ => false,
371 }
372 }
373}
374
375impl Data for Scale {
378 fn same(&self, other: &Self) -> bool {
379 self == other
380 }
381}
382
383impl Data for kurbo::Point {
384 fn same(&self, other: &Self) -> bool {
385 self.x.same(&other.x) && self.y.same(&other.y)
386 }
387}
388
389impl Data for kurbo::Vec2 {
390 fn same(&self, other: &Self) -> bool {
391 self.x.same(&other.x) && self.y.same(&other.y)
392 }
393}
394
395impl Data for kurbo::Size {
396 fn same(&self, other: &Self) -> bool {
397 self.width.same(&other.width) && self.height.same(&other.height)
398 }
399}
400
401impl Data for kurbo::Affine {
402 fn same(&self, other: &Self) -> bool {
403 let rhs = self.as_coeffs();
404 let lhs = other.as_coeffs();
405 rhs.iter().zip(lhs.iter()).all(|(r, l)| r.same(l))
406 }
407}
408
409impl Data for kurbo::Insets {
410 fn same(&self, other: &Self) -> bool {
411 self.x0.same(&other.x0)
412 && self.y0.same(&other.y0)
413 && self.x1.same(&other.x1)
414 && self.y1.same(&other.y1)
415 }
416}
417
418impl Data for kurbo::Rect {
419 fn same(&self, other: &Self) -> bool {
420 self.x0.same(&other.x0)
421 && self.y0.same(&other.y0)
422 && self.x1.same(&other.x1)
423 && self.y1.same(&other.y1)
424 }
425}
426
427impl Data for kurbo::RoundedRectRadii {
428 fn same(&self, other: &Self) -> bool {
429 self.top_left.same(&other.top_left)
430 && self.top_right.same(&other.top_right)
431 && self.bottom_left.same(&other.bottom_left)
432 && self.bottom_right.same(&other.bottom_right)
433 }
434}
435
436impl Data for kurbo::RoundedRect {
437 fn same(&self, other: &Self) -> bool {
438 self.rect().same(&other.rect()) && self.radii().same(&other.radii())
439 }
440}
441
442impl Data for kurbo::Arc {
443 fn same(&self, other: &Self) -> bool {
444 self.center.same(&other.center)
445 && self.radii.same(&other.radii)
446 && self.start_angle.same(&other.start_angle)
447 && self.sweep_angle.same(&other.sweep_angle)
448 && self.x_rotation.same(&other.x_rotation)
449 }
450}
451
452impl Data for kurbo::PathEl {
453 fn same(&self, other: &Self) -> bool {
454 use kurbo::PathEl::*;
455 match (self, other) {
456 (MoveTo(p1), MoveTo(p2)) => p1.same(p2),
457 (LineTo(p1), LineTo(p2)) => p1.same(p2),
458 (QuadTo(x1, y1), QuadTo(x2, y2)) => x1.same(x2) && y1.same(y2),
459 (CurveTo(x1, y1, z1), CurveTo(x2, y2, z2)) => x1.same(x2) && y1.same(y2) && z1.same(z2),
460 (ClosePath, ClosePath) => true,
461 _ => false,
462 }
463 }
464}
465
466impl Data for kurbo::PathSeg {
467 fn same(&self, other: &Self) -> bool {
468 use kurbo::PathSeg;
469 match (self, other) {
470 (PathSeg::Line(l1), PathSeg::Line(l2)) => l1.same(l2),
471 (PathSeg::Quad(q1), PathSeg::Quad(q2)) => q1.same(q2),
472 (PathSeg::Cubic(c1), PathSeg::Cubic(c2)) => c1.same(c2),
473 _ => false,
474 }
475 }
476}
477
478impl Data for kurbo::BezPath {
479 fn same(&self, other: &Self) -> bool {
480 let rhs = self.elements();
481 let lhs = other.elements();
482 if rhs.len() == lhs.len() {
483 rhs.iter().zip(lhs.iter()).all(|(x, y)| x.same(y))
484 } else {
485 false
486 }
487 }
488}
489
490impl Data for kurbo::Circle {
491 fn same(&self, other: &Self) -> bool {
492 self.center.same(&other.center) && self.radius.same(&other.radius)
493 }
494}
495
496impl Data for kurbo::CubicBez {
497 fn same(&self, other: &Self) -> bool {
498 self.p0.same(&other.p0)
499 && self.p1.same(&other.p1)
500 && self.p2.same(&other.p2)
501 && self.p3.same(&other.p3)
502 }
503}
504
505impl Data for kurbo::Line {
506 fn same(&self, other: &Self) -> bool {
507 self.p0.same(&other.p0) && self.p1.same(&other.p1)
508 }
509}
510
511impl Data for kurbo::ConstPoint {
512 fn same(&self, other: &Self) -> bool {
513 self.eval(0.).same(&other.eval(0.))
514 }
515}
516
517impl Data for kurbo::QuadBez {
518 fn same(&self, other: &Self) -> bool {
519 self.p0.same(&other.p0) && self.p1.same(&other.p1) && self.p2.same(&other.p2)
520 }
521}
522
523impl Data for piet::Color {
524 fn same(&self, other: &Self) -> bool {
525 self.as_rgba_u32().same(&other.as_rgba_u32())
526 }
527}
528
529impl Data for piet::FontFamily {
530 fn same(&self, other: &Self) -> bool {
531 self == other
532 }
533}
534
535impl Data for piet::FontWeight {
536 fn same(&self, other: &Self) -> bool {
537 self == other
538 }
539}
540
541impl Data for piet::FontStyle {
542 fn same(&self, other: &Self) -> bool {
543 self == other
544 }
545}
546
547impl Data for piet::TextAlignment {
548 fn same(&self, other: &Self) -> bool {
549 self == other
550 }
551}
552
553impl Data for ImageBuf {
554 fn same(&self, other: &Self) -> bool {
555 self.raw_pixels_shared().same(&other.raw_pixels_shared())
556 }
557}
558
559#[cfg(feature = "chrono")]
560impl<Tz: chrono::offset::TimeZone + 'static> Data for chrono::Date<Tz> {
561 fn same(&self, other: &Self) -> bool {
562 self == other
563 }
564}
565
566#[cfg(feature = "chrono")]
567impl<Tz: chrono::offset::TimeZone + 'static> Data for chrono::DateTime<Tz> {
568 fn same(&self, other: &Self) -> bool {
569 self == other
570 }
571}
572
573#[cfg(feature = "im")]
574impl<T: Data> Data for im::Vector<T> {
575 fn same(&self, other: &Self) -> bool {
576 if self.is_inline() {
579 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.same(b))
580 } else {
581 self.ptr_eq(other)
582 }
583 }
584}
585
586#[cfg(feature = "im")]
587impl<K: Clone + 'static, V: Data> Data for im::HashMap<K, V> {
588 fn same(&self, other: &Self) -> bool {
589 self.ptr_eq(other)
590 }
591}
592
593#[cfg(feature = "im")]
594impl<T: Data> Data for im::HashSet<T> {
595 fn same(&self, other: &Self) -> bool {
596 self.ptr_eq(other)
597 }
598}
599
600#[cfg(feature = "im")]
601impl<K: Clone + 'static, V: Data> Data for im::OrdMap<K, V> {
602 fn same(&self, other: &Self) -> bool {
603 self.ptr_eq(other)
604 }
605}
606
607#[cfg(feature = "im")]
608impl<T: Data> Data for im::OrdSet<T> {
609 fn same(&self, other: &Self) -> bool {
610 self.ptr_eq(other)
611 }
612}
613
614impl<T: Data, const N: usize> Data for [T; N] {
615 fn same(&self, other: &Self) -> bool {
616 self.iter().zip(other.iter()).all(|(a, b)| a.same(b))
617 }
618}
619
620#[cfg(test)]
621mod test {
622 use super::Data;
623 use test_log::test;
624
625 #[test]
626 fn array_data() {
627 let input = [1u8, 0, 0, 1, 0];
628 assert!(input.same(&[1u8, 0, 0, 1, 0]));
629 assert!(!input.same(&[1u8, 1, 0, 1, 0]));
630 }
631
632 #[test]
633 #[cfg(feature = "im")]
634 fn im_data() {
635 for len in 8..256 {
636 let input = std::iter::repeat(0_u8).take(len).collect::<im::Vector<_>>();
637 let mut inp2 = input.clone();
638 assert!(input.same(&inp2));
639 inp2.set(len - 1, 98);
640 assert!(!input.same(&inp2));
641 }
642 }
643
644 #[test]
645 #[cfg(feature = "im")]
646 fn im_vec_different_length() {
647 let one = std::iter::repeat(0_u8).take(9).collect::<im::Vector<_>>();
648 let two = std::iter::repeat(0_u8).take(10).collect::<im::Vector<_>>();
649 assert!(!one.same(&two));
650 }
651
652 #[test]
653 fn static_strings() {
654 let first = "test";
655 let same = "test";
656 let second = "test2";
657 assert!(!Data::same(&first, &second));
658 assert!(Data::same(&first, &first));
659 assert!(Data::same(&first, &same));
662 }
663}