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}