simple_interner/
interned.rs

1use std::{borrow::Borrow, ops::Deref, ptr};
2
3/// An item interned by an `Interner`.
4///
5/// As two equal interned items will always be the same reference, only the
6/// reference is compared for equality rather than going to the potentially
7/// expensive `PartialEq` implementation on the concrete type.
8///
9/// In all other cases, this should act exactly as if it were a reference to the
10/// wrapped type. To get the wrapped reference with the full lifetime, see
11/// [`Interned::get`].
12#[derive(Debug, Ord, PartialOrd, Hash)]
13pub struct Interned<'a, T: ?Sized>(pub(crate) &'a T);
14
15impl<'a, T: ?Sized> Interned<'a, T> {
16    /// Get the wrapped reference out directly.
17    ///
18    /// This is an associated function rather than a method in order to
19    /// avoid conflicting with implementations on the concrete type.
20    pub fn get(this: &Self) -> &'a T {
21        this.0
22    }
23}
24
25impl<T: ?Sized> Copy for Interned<'_, T> {}
26impl<T: ?Sized> Clone for Interned<'_, T> {
27    fn clone(&self) -> Self {
28        *self
29    }
30}
31
32impl<T: ?Sized> Eq for Interned<'_, T> {}
33impl<T: ?Sized> PartialEq for Interned<'_, T> {
34    fn eq(&self, other: &Self) -> bool {
35        ptr::eq(self.0, other.0)
36    }
37}
38
39impl<T: ?Sized> Deref for Interned<'_, T> {
40    type Target = T;
41    fn deref(&self) -> &T {
42        self.0
43    }
44}
45
46impl<T: ?Sized> Borrow<T> for Interned<'_, T> {
47    fn borrow(&self) -> &T {
48        self
49    }
50}
51
52impl<T, U> AsRef<U> for Interned<'_, T>
53where
54    T: AsRef<U> + ?Sized,
55    U: ?Sized,
56{
57    fn as_ref(&self) -> &U {
58        (**self).as_ref()
59    }
60}