Skip to main content

musli/alloc/
slice_buffer.rs

1use core::mem::MaybeUninit;
2use core::slice::from_raw_parts_mut;
3
4use super::ArrayBuffer;
5
6mod sealed {
7    use core::mem::MaybeUninit;
8
9    use super::super::ArrayBuffer;
10
11    pub trait Sealed {}
12    impl Sealed for [MaybeUninit<u8>] {}
13    impl Sealed for [MaybeUninit<u16>] {}
14    impl Sealed for [MaybeUninit<u32>] {}
15    impl Sealed for [MaybeUninit<u64>] {}
16    impl Sealed for [MaybeUninit<u128>] {}
17    impl<const N: usize> Sealed for [MaybeUninit<u8>; N] {}
18    impl<const N: usize> Sealed for [MaybeUninit<u16>; N] {}
19    impl<const N: usize> Sealed for [MaybeUninit<u32>; N] {}
20    impl<const N: usize> Sealed for [MaybeUninit<u64>; N] {}
21    impl<const N: usize> Sealed for [MaybeUninit<u128>; N] {}
22    impl Sealed for [u8] {}
23    impl Sealed for [u16] {}
24    impl Sealed for [u32] {}
25    impl Sealed for [u64] {}
26    impl Sealed for [u128] {}
27    impl<const N: usize> Sealed for [u8; N] {}
28    impl<const N: usize> Sealed for [u16; N] {}
29    impl<const N: usize> Sealed for [u32; N] {}
30    impl<const N: usize> Sealed for [u64; N] {}
31    impl<const N: usize> Sealed for [u128; N] {}
32    impl<const N: usize> Sealed for ArrayBuffer<N> {}
33}
34
35/// The trait over anything that can be treated as a buffer by the [`Slice`]
36/// allocator.
37///
38/// [`Slice`]: super::Slice
39pub trait SliceBuffer: self::sealed::Sealed {
40    #[doc(hidden)]
41    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>];
42}
43
44/// The [`SliceBuffer`] implementation for `[u8]`.
45///
46/// # Examples
47///
48/// ```
49/// use musli::alloc::Slice;
50///
51/// let mut bytes = [0u8; 128];
52/// let alloc = Slice::new(&mut bytes[..]);
53/// ```
54impl SliceBuffer for [u8] {
55    #[inline]
56    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
57        // SAFEYT: &mut [u8] has the same layout as &mut [MaybeUninit<u8>]
58        unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), self.len()) }
59    }
60}
61
62/// The [`SliceBuffer`] implementation for `[u8; N]`.
63///
64/// # Examples
65///
66/// ```
67/// use musli::alloc::Slice;
68///
69/// let mut bytes = [0u8; 128];
70/// let alloc = Slice::new(&mut bytes);
71/// ```
72impl<const N: usize> SliceBuffer for [u8; N] {
73    #[inline]
74    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
75        self.as_mut_slice().as_uninit_bytes()
76    }
77}
78
79/// The [`SliceBuffer`] implementation for `[MaybeUninit<u8>]`.
80///
81/// # Examples
82///
83/// ```
84/// use core::mem::MaybeUninit;
85///
86/// use musli::alloc::Slice;
87///
88/// let mut bytes: [MaybeUninit<u8>; 128] = [const { MaybeUninit::uninit() }; 128];
89/// let alloc = Slice::new(&mut bytes[..]);
90/// ```
91impl SliceBuffer for [MaybeUninit<u8>] {
92    #[inline]
93    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
94        self
95    }
96}
97
98/// The [`SliceBuffer`] implementation for `[MaybeUninit<u8>; N]`.
99///
100/// # Examples
101///
102/// ```
103/// use core::mem::MaybeUninit;
104///
105/// # use musli::alloc::SliceBuffer as _;
106/// use musli::alloc::Slice;
107///
108/// let mut bytes: [MaybeUninit<u8>; 128] = [const { MaybeUninit::uninit() }; 128];
109/// # assert_eq!(bytes.as_uninit_bytes().len(), 128);
110/// let alloc = Slice::new(&mut bytes);
111/// ```
112impl<const N: usize> SliceBuffer for [MaybeUninit<u8>; N] {
113    #[inline]
114    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
115        self
116    }
117}
118
119/// The [`SliceBuffer`] implementation for `ArrayBuffer<N>`.
120///
121/// # Examples
122///
123/// ```
124/// use core::mem::MaybeUninit;
125///
126/// use musli::alloc::{ArrayBuffer, Slice};
127///
128/// let mut buffer = ArrayBuffer::new();
129/// let alloc = Slice::new(&mut buffer);
130/// ```
131impl<const N: usize> SliceBuffer for ArrayBuffer<N> {
132    #[inline]
133    fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
134        self
135    }
136}
137
138macro_rules! primitive {
139    ($($ty:ty, $len:expr),* $(,)?) => {
140        $(
141            #[doc = concat!(" The [`SliceBuffer`] implementation for `[", stringify!($ty), "]`.")]
142            ///
143            /// # Examples
144            ///
145            /// ```
146            /// use musli::alloc::Slice;
147            /// # use musli::alloc::SliceBuffer as _;
148            ///
149            #[doc = concat!(" let mut bytes = [0", stringify!($ty), "; 128];")]
150            #[doc = concat!(" # assert_eq!(bytes.as_uninit_bytes().len(), ", stringify!($len), ");")]
151            /// let alloc = Slice::new(&mut bytes[..]);
152            /// ```
153            impl SliceBuffer for [$ty] {
154                #[inline]
155                fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
156                    // SAFEYT: &mut [u8] has the same layout as &mut [MaybeUninit<u8>]
157                    unsafe {
158                        let len = <[_]>::len(self) * (<$ty>::BITS / 8u32) as usize;
159                        from_raw_parts_mut(self.as_mut_ptr().cast(), len)
160                    }
161                }
162            }
163
164            #[doc = concat!(" The [`SliceBuffer`] implementation for `[MaybeUninit<", stringify!($ty), ">]`.")]
165            ///
166            /// # Examples
167            ///
168            /// ```
169            /// use core::mem::MaybeUninit;
170            ///
171            /// use musli::alloc::Slice;
172            /// # use musli::alloc::SliceBuffer as _;
173            ///
174            #[doc = concat!(" let mut bytes: [MaybeUninit<", stringify!($ty), ">; 128] = [const { MaybeUninit::uninit() }; 128];")]
175            #[doc = concat!(" # assert_eq!(bytes.as_uninit_bytes().len(), ", stringify!($len), ");")]
176            /// let alloc = Slice::new(&mut bytes[..]);
177            /// ```
178            impl SliceBuffer for [MaybeUninit<$ty>] {
179                #[inline]
180                fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
181                    // SAFEYT: &mut [u8] has the same layout as &mut [MaybeUninit<u8>]
182                    unsafe {
183                        let len = <[_]>::len(self) * (<$ty>::BITS / 8u32) as usize;
184                        from_raw_parts_mut(self.as_mut_ptr().cast(), len)
185                    }
186                }
187            }
188
189            #[doc = concat!(" The [`SliceBuffer`] implementation for `[", stringify!($ty), "]`.")]
190            ///
191            /// # Examples
192            ///
193            /// ```
194            /// use core::mem::MaybeUninit;
195            ///
196            /// use musli::alloc::Slice;
197            /// # use musli::alloc::SliceBuffer as _;
198            ///
199            #[doc = concat!(" let mut bytes = [0", stringify!($ty), "; 128];")]
200            #[doc = concat!(" # assert_eq!(bytes.as_uninit_bytes().len(), ", stringify!($len), ");")]
201            /// let alloc = Slice::new(&mut bytes);
202            /// ```
203            impl<const N: usize> SliceBuffer for [$ty; N] {
204                #[inline]
205                fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
206                    self.as_mut_slice().as_uninit_bytes()
207                }
208            }
209
210            #[doc = concat!(" The [`SliceBuffer`] implementation for `[MaybeUninit<", stringify!($ty), ">; N]`.")]
211            ///
212            /// # Examples
213            ///
214            /// ```
215            /// use musli::alloc::Slice;
216            /// # use musli::alloc::SliceBuffer as _;
217            ///
218            #[doc = concat!(" let mut bytes = [0", stringify!($ty), "; 128];")]
219            #[doc = concat!(" # assert_eq!(bytes.as_uninit_bytes().len(), ", stringify!($len), ");")]
220            /// let alloc = Slice::new(&mut bytes);
221            /// ```
222            impl<const N: usize> SliceBuffer for [MaybeUninit<$ty>; N] {
223                #[inline]
224                fn as_uninit_bytes(&mut self) -> &mut [MaybeUninit<u8>] {
225                    self.as_mut_slice().as_uninit_bytes()
226                }
227            }
228        )*
229    }
230}
231
232primitive! {
233    u16, 128 * 2,
234    u32, 128 * 4,
235    u64, 128 * 8,
236    u128, 128 * 16,
237}