1use std::{
2 any::{Any, TypeId},
3 hash::{Hash, Hasher},
4};
5
6pub trait DynPartialEq: Any {
9 fn dyn_partial_eq(&self, other: &dyn Any) -> bool;
10}
11
12impl<T: Any + PartialEq> DynPartialEq for T {
13 fn dyn_partial_eq(&self, other: &dyn Any) -> bool {
14 other
15 .downcast_ref::<Self>()
16 .map(|other| PartialEq::eq(self, other))
17 .unwrap_or(false)
18 }
19}
20
21#[macro_export]
22macro_rules! impl_partial_eq_for_dyn {
23 ($ty:ty) => {
24 impl ::std::cmp::PartialEq for $ty {
25 fn eq(&self, other: &Self) -> bool {
26 $crate::DynPartialEq::dyn_partial_eq(self, other as &dyn ::std::any::Any)
27 }
28 }
29 };
30}
31
32pub trait DynEq: DynPartialEq {}
35
36impl<T: Any + Eq> DynEq for T {}
37
38#[macro_export]
39macro_rules! impl_eq_for_dyn {
40 ($ty:ty) => {
41 impl ::std::cmp::Eq for $ty {}
42 };
43}
44
45pub trait DynHash {
52 fn dyn_hash(&self, state: &mut dyn Hasher);
53}
54
55impl<T: Any + Hash> DynHash for T {
56 fn dyn_hash(&self, mut state: &mut dyn Hasher) {
57 Hash::hash(&(TypeId::of::<Self>(), self), &mut state);
58 }
59}
60
61#[macro_export]
62macro_rules! impl_hash_for_dyn {
63 ($ty:ty) => {
64 impl ::std::hash::Hash for $ty {
65 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
66 $crate::DynHash::dyn_hash(self, state as &mut dyn (::std::hash::Hasher))
67 }
68 }
69 };
70}