tessera_ui/dyn_eq_compute.rs
1use std::any::Any;
2
3use crate::ComputeCommand;
4
5/// A trait that allows for cloning a trait object.
6pub trait DynCloneCompute {
7 /// Creates a boxed clone of the trait object.
8 fn clone_box(&self) -> Box<dyn ComputeCommand>;
9}
10
11impl<T> DynCloneCompute for T
12where
13 T: ComputeCommand + Clone + 'static,
14{
15 fn clone_box(&self) -> Box<dyn ComputeCommand> {
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 DynPartialEqCompute: DynCloneCompute {
26 /// Returns the object as a `&dyn Any`.
27 fn as_any(&self) -> &dyn Any;
28
29 /// Performs a dynamic equality check against another `DynPartialEqCompute` trait object.
30 fn dyn_eq(&self, other: &dyn DynPartialEqCompute) -> bool;
31}
32
33impl<T: ComputeCommand + PartialEq + 'static> DynPartialEqCompute for T {
34 fn as_any(&self) -> &dyn Any {
35 self
36 }
37
38 fn dyn_eq(&self, other: &dyn DynPartialEqCompute) -> 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}