pointer_identity/
identity.rs

1use crate::Pointer;
2use std::{
3    cmp::Ordering,
4    hash::{Hash, Hasher},
5    ops::{Deref, DerefMut},
6};
7
8/// Wrapper type that uses the pointer address rather than the value as the identity for the
9/// [`PartialEq`], [`Eq`], [`PartialOrd`], [`Ord`] and [`Hash`] traits.
10///
11/// This wrapper is transparent thanks to implementing both [`Deref`] and [`DerefMut`], so you can
12/// use an instance of this just like you would use an instance of the type you are wrapping.
13#[derive(Debug, Clone, Copy, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct PointerIdentity<P: Pointer>(pub P);
16
17impl<P: Pointer> PointerIdentity<P> {
18    /// Create new from a pointer.
19    pub fn new(value: P) -> Self {
20        Self(value)
21    }
22
23    /// Get reference to inner value.
24    pub fn inner(&self) -> &P {
25        &self.0
26    }
27
28    /// Convert into inner value.
29    pub fn into_inner(self) -> P {
30        self.0
31    }
32}
33
34impl<P: Pointer> From<P> for PointerIdentity<P> {
35    fn from(value: P) -> Self {
36        Self::new(value)
37    }
38}
39
40impl<P: Pointer> PartialEq for PointerIdentity<P> {
41    fn eq(&self, other: &Self) -> bool {
42        self.0.get() == other.0.get()
43    }
44}
45
46impl<P: Pointer> Eq for PointerIdentity<P> {}
47
48impl<P: Pointer> PartialOrd for PointerIdentity<P> {
49    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
50        Some(self.0.get().cmp(&other.0.get()))
51    }
52}
53
54impl<P: Pointer> Ord for PointerIdentity<P> {
55    fn cmp(&self, other: &Self) -> Ordering {
56        self.0.get().cmp(&other.0.get())
57    }
58}
59
60impl<P: Pointer> Hash for PointerIdentity<P> {
61    fn hash<H: Hasher>(&self, state: &mut H) {
62        self.0.get().hash(state);
63    }
64}
65
66impl<P: Pointer> Deref for PointerIdentity<P> {
67    type Target = P;
68
69    fn deref(&self) -> &Self::Target {
70        &self.0
71    }
72}
73
74impl<P: Pointer> DerefMut for PointerIdentity<P> {
75    fn deref_mut(&mut self) -> &mut Self::Target {
76        &mut self.0
77    }
78}