musli/alloc/array_buffer.rs
1use core::mem::MaybeUninit;
2use core::ops::{Deref, DerefMut};
3
4use super::DEFAULT_ARRAY_BUFFER;
5
6/// An array that can conveniently be used as a buffer, by default this is
7/// [`DEFAULT_ARRAY_BUFFER`] bytes large.
8///
9/// This is aligned to 8 bytes, since that's an alignment which works with many
10/// common Rust types.
11///
12/// See the [module level documentation][super] for more information.
13#[repr(align(8))]
14pub struct ArrayBuffer<const N: usize = DEFAULT_ARRAY_BUFFER> {
15 data: [MaybeUninit<u8>; N],
16}
17
18impl ArrayBuffer {
19 /// Construct a new buffer with the default size of
20 /// [`DEFAULT_ARRAY_BUFFER`].
21 ///
22 /// # Examples
23 ///
24 /// ```
25 /// use musli::alloc::ArrayBuffer;
26 ///
27 /// let buffer = ArrayBuffer::new();
28 /// assert_eq!(buffer.len(), 4096);
29 /// ```
30 pub const fn new() -> Self {
31 Self::with_size()
32 }
33}
34
35impl Default for ArrayBuffer {
36 #[inline]
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42impl<const N: usize> ArrayBuffer<N> {
43 /// Construct a new buffer with a custom size.
44 ///
45 /// # Examples
46 ///
47 /// ```
48 /// use musli::alloc::ArrayBuffer;
49 ///
50 /// let buffer = ArrayBuffer::<1024>::with_size();
51 /// assert_eq!(buffer.len(), 1024);
52 /// ```
53 pub const fn with_size() -> Self {
54 Self {
55 // SAFETY: This is safe to initialize, since it's just an array of
56 // contiguous uninitialized memory.
57 data: unsafe { MaybeUninit::uninit().assume_init() },
58 }
59 }
60}
61
62impl<const N: usize> Deref for ArrayBuffer<N> {
63 type Target = [MaybeUninit<u8>];
64
65 #[inline]
66 fn deref(&self) -> &Self::Target {
67 &self.data
68 }
69}
70
71impl<const N: usize> DerefMut for ArrayBuffer<N> {
72 #[inline]
73 fn deref_mut(&mut self) -> &mut Self::Target {
74 &mut self.data
75 }
76}