tessera_ui/dyn_eq.rs
1use std::any::Any;
2
3use crate::renderer::drawer::DrawCommand;
4
5/// A trait that allows for cloning a trait object.
6pub trait DynCloneDraw {
7 /// Creates a boxed clone of the trait object.
8 fn clone_box(&self) -> Box<dyn DrawCommand>;
9}
10
11impl<T> DynCloneDraw for T
12where
13 T: DrawCommand + Clone + 'static,
14{
15 fn clone_box(&self) -> Box<dyn DrawCommand> {
16 Box::new(self.clone())
17 }
18}
19
20/// A trait that allows for dynamic equality testing of trait objects.
21///
22/// This trait provides a workaround for the fact that `PartialEq` is not object-safe.
23/// It allows types that are `PartialEq` to be compared even when they are behind
24/// a trait object by downcasting them to their concrete types.
25pub trait DynPartialEqDraw: DynCloneDraw {
26 /// Returns the object as a `&dyn Any`.
27 fn as_any(&self) -> &dyn Any;
28
29 /// Performs a dynamic equality check against another `DynPartialEqDraw` trait object.
30 fn dyn_eq(&self, other: &dyn DynPartialEqDraw) -> bool;
31}
32
33impl<T: DrawCommand + PartialEq + 'static> DynPartialEqDraw for T {
34 fn as_any(&self) -> &dyn Any {
35 self
36 }
37
38 fn dyn_eq(&self, other: &dyn DynPartialEqDraw) -> bool {
39 // Attempt to downcast the `other` trait object to the same concrete type as `self`.
40 if let Some(other_concrete) = other.as_any().downcast_ref::<T>() {
41 // If the downcast is successful, perform the actual comparison.
42 self == other_concrete
43 } else {
44 // If the types are different, they cannot be equal.
45 false
46 }
47 }
48}