enum_ptr/traits/
borrow.rs

1use core::mem::transmute;
2use core::ops::Deref;
3
4use crate::{Compact, Compactable};
5
6/// Types that can be borrowed from [`Compact`]. Typically derived from
7/// [`EnumPtr`](crate::EnumPtr).
8pub trait CompactBorrow: Compactable {
9    type Target<'a>
10    where
11        Self: 'a;
12
13    fn borrow(compact: &Compact<Self>) -> Self::Target<'_>;
14}
15
16/// Types that can be used by [`get_ref`](crate::get_ref) and to derive
17/// [`CompactBorrow`].
18///
19/// It's like [`Deref`] but with flexible targets and strict constraints.
20///
21/// # Safety
22///
23/// `T` must not `deref` to something that points to its own memory.
24///
25/// A counter-example is `ManuallyDrop<T>`, which will `deref` to `&T`.
26pub unsafe trait FieldDeref {
27    type Target<'a>
28    where
29        Self: 'a;
30
31    fn deref(&self) -> Self::Target<'_>;
32
33    #[doc(hidden)]
34    #[inline]
35    unsafe fn force_deref<'a>(&self) -> Self::Target<'a> {
36        transmute(self.deref())
37    }
38}
39
40unsafe impl<T> FieldDeref for &T {
41    type Target<'a> = &'a T
42    where
43        Self: 'a;
44
45    #[inline]
46    fn deref(&self) -> Self::Target<'_> {
47        Deref::deref(self)
48    }
49}
50
51unsafe impl<T> FieldDeref for &mut T {
52    type Target<'a> = &'a T
53    where
54        Self: 'a;
55
56    #[inline]
57    fn deref(&self) -> Self::Target<'_> {
58        Deref::deref(self)
59    }
60}
61
62unsafe impl<T> FieldDeref for Option<&T> {
63    type Target<'a> = Option<&'a T>
64    where
65        Self: 'a;
66
67    #[inline]
68    fn deref(&self) -> Self::Target<'_> {
69        self.as_deref()
70    }
71}
72
73unsafe impl<T> FieldDeref for Option<&mut T> {
74    type Target<'a> = Option<&'a T>
75    where
76        Self: 'a;
77
78    #[inline]
79    fn deref(&self) -> Self::Target<'_> {
80        self.as_deref()
81    }
82}
83
84#[cfg(feature = "alloc")]
85mod alloc_impl {
86    use super::*;
87
88    use alloc::boxed::Box;
89    use alloc::rc::Rc;
90    use alloc::sync::Arc;
91
92    unsafe impl<T> FieldDeref for Box<T> {
93        type Target<'a> = &'a T
94        where
95            Self: 'a;
96
97        #[inline]
98        fn deref(&self) -> Self::Target<'_> {
99            Deref::deref(self)
100        }
101    }
102
103    unsafe impl<T> FieldDeref for Rc<T> {
104        type Target<'a> = &'a T
105        where
106            Self: 'a;
107
108        #[inline]
109        fn deref(&self) -> Self::Target<'_> {
110            Deref::deref(self)
111        }
112    }
113
114    unsafe impl<T> FieldDeref for Arc<T> {
115        type Target<'a> = &'a T
116        where
117            Self: 'a;
118
119        #[inline]
120        fn deref(&self) -> Self::Target<'_> {
121            Deref::deref(self)
122        }
123    }
124
125    unsafe impl<T> FieldDeref for Option<Box<T>> {
126        type Target<'a> = Option<&'a T>
127        where
128            Self: 'a;
129
130        #[inline]
131        fn deref(&self) -> Self::Target<'_> {
132            self.as_deref()
133        }
134    }
135
136    unsafe impl<T> FieldDeref for Option<Rc<T>> {
137        type Target<'a> = Option<&'a T>
138        where
139            Self: 'a;
140
141        #[inline]
142        fn deref(&self) -> Self::Target<'_> {
143            self.as_deref()
144        }
145    }
146
147    unsafe impl<T> FieldDeref for Option<Arc<T>> {
148        type Target<'a> = Option<&'a T>
149        where
150            Self: 'a;
151
152        #[inline]
153        fn deref(&self) -> Self::Target<'_> {
154            self.as_deref()
155        }
156    }
157}