fidl_next_codec/
slot.rs
1use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::ops::{Deref, DerefMut};
8use core::ptr::slice_from_raw_parts_mut;
9use core::slice::from_raw_parts;
10
11use munge::{Destructure, Move, Restructure};
12use zerocopy::{FromBytes, IntoBytes};
13
14#[repr(transparent)]
20pub struct Slot<'buf, T: ?Sized> {
21 ptr: *mut T,
22 _phantom: PhantomData<&'buf mut [u8]>,
23}
24
25impl<'buf, T: ?Sized> Slot<'buf, T> {
26 pub fn new(backing: &'buf mut MaybeUninit<T>) -> Self
28 where
29 T: Sized,
30 {
31 unsafe {
32 backing.as_mut_ptr().write_bytes(0, 1);
33 }
34 unsafe { Self::new_unchecked(backing.as_mut_ptr()) }
35 }
36
37 pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
44 Self { ptr, _phantom: PhantomData }
45 }
46
47 pub fn as_mut(&mut self) -> Slot<'_, T> {
49 Self { ptr: self.ptr, _phantom: PhantomData }
50 }
51
52 pub fn as_mut_ptr(&mut self) -> *mut T {
54 self.ptr
55 }
56
57 pub fn as_ptr(&self) -> *const T {
59 self.ptr
60 }
61
62 pub unsafe fn deref_unchecked(&self) -> &T {
68 unsafe { &*self.as_ptr() }
69 }
70
71 pub unsafe fn deref_mut_unchecked(&mut self) -> &mut T {
77 unsafe { &mut *self.as_mut_ptr() }
78 }
79
80 pub fn write(&mut self, value: T)
82 where
83 T: IntoBytes + Sized,
84 {
85 unsafe {
86 self.as_mut_ptr().write(value);
87 }
88 }
89}
90
91impl<T> Slot<'_, T> {
92 pub fn as_bytes(&self) -> &[u8] {
94 unsafe { from_raw_parts(self.ptr.cast::<u8>(), size_of::<T>()) }
95 }
96}
97
98impl<T, const N: usize> Slot<'_, [T; N]> {
99 pub fn index(&mut self, index: usize) -> Slot<'_, T> {
101 assert!(index < N, "attempted to index out-of-bounds");
102
103 Slot { ptr: unsafe { self.as_mut_ptr().cast::<T>().add(index) }, _phantom: PhantomData }
104 }
105}
106
107impl<T> Slot<'_, [T]> {
108 pub unsafe fn new_slice_unchecked(ptr: *mut T, len: usize) -> Self {
115 Self { ptr: slice_from_raw_parts_mut(ptr, len), _phantom: PhantomData }
116 }
117
118 pub fn index(&mut self, index: usize) -> Slot<'_, T> {
120 assert!(index < self.ptr.len(), "attempted to index out-of-bounds");
121
122 Slot { ptr: unsafe { self.as_mut_ptr().cast::<T>().add(index) }, _phantom: PhantomData }
123 }
124}
125
126impl<T: FromBytes> Deref for Slot<'_, T> {
127 type Target = T;
128
129 fn deref(&self) -> &Self::Target {
130 unsafe { &*self.as_ptr() }
131 }
132}
133
134impl<T: FromBytes> DerefMut for Slot<'_, T> {
135 fn deref_mut(&mut self) -> &mut Self::Target {
136 unsafe { &mut *self.as_mut_ptr() }
137 }
138}
139
140impl<'buf, T> Iterator for Slot<'buf, [T]> {
141 type Item = Slot<'buf, T>;
142
143 fn next(&mut self) -> Option<Self::Item> {
144 if self.ptr.len() == 0 {
145 return None;
146 }
147
148 let result = Slot { ptr: self.ptr.cast::<T>(), _phantom: PhantomData };
149
150 self.ptr =
151 slice_from_raw_parts_mut(unsafe { self.ptr.cast::<T>().add(1) }, self.ptr.len() - 1);
152
153 Some(result)
154 }
155}
156
157unsafe impl<T> Destructure for Slot<'_, T> {
158 type Underlying = T;
159 type Destructuring = Move;
160
161 fn underlying(&mut self) -> *mut Self::Underlying {
162 self.as_mut_ptr()
163 }
164}
165
166unsafe impl<'buf, T, U: 'buf> Restructure<U> for Slot<'buf, T> {
167 type Restructured = Slot<'buf, U>;
168
169 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
170 Slot { ptr, _phantom: PhantomData }
171 }
172}