musli_zerocopy/pointer/
pointee.rs

1use core::fmt;
2
3use crate::error::IntoRepr;
4use crate::pointer::Size;
5use crate::traits::ZeroCopy;
6
7mod sealed {
8    use crate::mem::MaybeUninit;
9    use crate::pointer::Pointee;
10    use crate::traits::ZeroCopy;
11
12    pub trait Sealed {}
13
14    impl<T> Sealed for MaybeUninit<T> where T: Pointee {}
15    impl<T> Sealed for T where T: ZeroCopy {}
16    impl<T> Sealed for [T] where T: ZeroCopy {}
17    impl Sealed for str {}
18}
19
20/// The trait for a value that can be pointed to by a [`Ref<T>`].
21///
22/// This ultimately determines the layout of [`Ref<T>`] as for unsized types it
23/// needs to accommodate the size of the pointed-to type as well.
24///
25/// ```
26/// use std::mem::size_of;
27///
28/// use musli_zerocopy::Ref;
29///
30/// assert_eq!(size_of::<Ref::<u32>>(), 4);
31/// assert_eq!(size_of::<Ref::<[u32]>>(), 8);
32/// ```
33///
34/// [`Ref<T>`]: crate::Ref
35pub trait Pointee: self::sealed::Sealed {
36    /// Metadata associated with a pointee.
37    type Metadata: Copy + fmt::Debug + IntoRepr;
38
39    /// The stored representation of the pointee metadata.
40    #[doc(hidden)]
41    type Stored<O>: Copy + ZeroCopy
42    where
43        O: Size;
44
45    /// Try to construct packed value from its metadata.
46    #[doc(hidden)]
47    fn try_from_metadata<O>(metadata: Self::Metadata) -> Option<Self::Stored<O>>
48    where
49        O: Size;
50}
51
52impl<T> Pointee for T
53where
54    T: ZeroCopy,
55{
56    type Metadata = ();
57    type Stored<O>
58        = ()
59    where
60        O: Size;
61
62    #[inline(always)]
63    fn try_from_metadata<O>((): ()) -> Option<Self::Stored<O>>
64    where
65        O: Size,
66    {
67        Some(())
68    }
69}
70
71impl<T> Pointee for [T]
72where
73    T: ZeroCopy,
74{
75    type Metadata = usize;
76    type Stored<O>
77        = O
78    where
79        O: Size;
80
81    #[inline(always)]
82    fn try_from_metadata<O>(metadata: usize) -> Option<O>
83    where
84        O: Size,
85    {
86        O::try_from_usize(metadata)
87    }
88}
89
90impl Pointee for str {
91    type Metadata = usize;
92    type Stored<O>
93        = O
94    where
95        O: Size;
96
97    #[inline(always)]
98    fn try_from_metadata<O>(metadata: usize) -> Option<O>
99    where
100        O: Size,
101    {
102        O::try_from_usize(metadata)
103    }
104}