Skip to main content

keyed/
ref_keyed.rs

1use core::cmp::Ordering;
2use core::hash::{Hash, Hasher};
3
4/// Trait for extracting key that is a reference to internal data from a data structure.
5pub trait RefKey {
6    /// Type of the key.
7    type Output;
8
9    /// Extract the key from the data structure.
10    fn key(&self) -> &Self::Output;
11}
12
13/// A wrapper for data structures that implements [`RefKey`](`RefKey`) trait.
14#[derive(Clone, Copy, Debug, Default)]
15pub struct RefKeyed<T>(pub T);
16
17impl<T> From<T> for RefKeyed<T> {
18    fn from(value: T) -> Self {
19        Self(value)
20    }
21}
22
23impl<T: RefKey> PartialEq for RefKeyed<T>
24where
25    T::Output: PartialEq,
26{
27    fn eq(&self, other: &Self) -> bool {
28        self.0.key().eq(other.0.key())
29    }
30
31    #[allow(clippy::partialeq_ne_impl)]
32    fn ne(&self, other: &Self) -> bool {
33        self.0.key().ne(other.0.key())
34    }
35}
36
37impl<T: RefKey> Eq for RefKeyed<T> where T::Output: Eq {}
38
39impl<T: RefKey> PartialOrd for RefKeyed<T>
40where
41    T::Output: PartialOrd,
42{
43    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
44        self.0.key().partial_cmp(other.0.key())
45    }
46
47    fn lt(&self, other: &Self) -> bool {
48        self.0.key().lt(other.0.key())
49    }
50
51    fn le(&self, other: &Self) -> bool {
52        self.0.key().le(other.0.key())
53    }
54
55    fn gt(&self, other: &Self) -> bool {
56        self.0.key().gt(other.0.key())
57    }
58
59    fn ge(&self, other: &Self) -> bool {
60        self.0.key().ge(other.0.key())
61    }
62}
63
64impl<T: RefKey> Ord for RefKeyed<T>
65where
66    T::Output: Ord,
67{
68    fn cmp(&self, other: &Self) -> Ordering {
69        self.0.key().cmp(other.0.key())
70    }
71}
72
73impl<T: RefKey> Hash for RefKeyed<T>
74where
75    T::Output: Hash,
76{
77    fn hash<H: Hasher>(&self, state: &mut H) {
78        self.0.key().hash(state)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::super::tests::{self, KeyValuePair};
85    use super::{RefKey, RefKeyed};
86
87    impl<K, V> RefKey for KeyValuePair<K, V> {
88        type Output = K;
89
90        fn key(&self) -> &Self::Output {
91            &self.key
92        }
93    }
94
95    #[test]
96    fn test_partial_eq() {
97        tests::test_partial_eq(RefKeyed);
98    }
99
100    #[test]
101    fn test_eq() {
102        tests::test_eq(RefKeyed);
103    }
104
105    #[test]
106    fn test_partial_ord() {
107        tests::test_partial_ord(RefKeyed);
108    }
109
110    #[test]
111    fn test_ord() {
112        tests::test_ord(RefKeyed);
113    }
114
115    #[test]
116    fn test_hash() {
117        tests::test_hash(RefKeyed);
118    }
119}