musli_core/internal/
fixed.rs
1use core::fmt;
2use core::mem::{self, ManuallyDrop, MaybeUninit};
3use core::ops::{Deref, DerefMut};
4use core::ptr;
5use core::slice;
6
7#[derive(Debug)]
9#[non_exhaustive]
10pub(crate) struct CapacityError;
11
12impl fmt::Display for CapacityError {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 f.write_str("Out of capacity when constructing array")
15 }
16}
17
18impl core::error::Error for CapacityError {}
19
20pub(crate) struct FixedVec<T, const N: usize> {
22 data: [MaybeUninit<T>; N],
23 len: usize,
24}
25
26impl<T, const N: usize> FixedVec<T, N> {
27 pub(crate) const fn new() -> FixedVec<T, N> {
29 unsafe {
30 FixedVec {
31 data: MaybeUninit::uninit().assume_init(),
32 len: 0,
33 }
34 }
35 }
36
37 #[inline]
38 pub(crate) fn as_ptr(&self) -> *const T {
39 self.data.as_ptr() as *const T
40 }
41
42 #[inline]
43 pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
44 self.data.as_mut_ptr() as *mut T
45 }
46
47 #[inline]
48 pub(crate) fn as_slice(&self) -> &[T] {
49 unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
50 }
51
52 #[inline]
53 pub(crate) fn as_mut_slice(&mut self) -> &mut [T] {
54 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
55 }
56
57 pub(crate) fn try_push(&mut self, element: T) -> Result<(), CapacityError> {
59 if self.len >= N {
60 return Err(CapacityError);
61 }
62
63 unsafe {
64 ptr::write(self.as_mut_ptr().wrapping_add(self.len), element);
65 self.len += 1;
66 }
67
68 Ok(())
69 }
70
71 pub(crate) fn clear(&mut self) {
72 if self.len == 0 {
73 return;
74 }
75
76 let len = mem::take(&mut self.len);
77
78 if mem::needs_drop::<T>() {
79 unsafe {
80 let tail = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
81 ptr::drop_in_place(tail);
82 }
83 }
84 }
85
86 pub(crate) fn into_inner(self) -> [T; N] {
87 assert!(
88 self.len == N,
89 "into_inner: length mismatch, expected {N} but got {}",
90 self.len
91 );
92
93 unsafe {
95 let this = ManuallyDrop::new(self);
96 ptr::read(this.data.as_ptr() as *const [T; N])
97 }
98 }
99}
100
101impl<T, const N: usize> Deref for FixedVec<T, N> {
102 type Target = [T];
103
104 #[inline]
105 fn deref(&self) -> &Self::Target {
106 self.as_slice()
107 }
108}
109
110impl<T, const N: usize> DerefMut for FixedVec<T, N> {
111 #[inline]
112 fn deref_mut(&mut self) -> &mut Self::Target {
113 self.as_mut_slice()
114 }
115}
116
117impl<T, const N: usize> Drop for FixedVec<T, N> {
118 #[inline]
119 fn drop(&mut self) {
120 self.clear()
121 }
122}