1use std::{
16 marker::PhantomData,
17 mem,
18 mem::MaybeUninit,
19 ops::{Deref, DerefMut},
20};
21
22use zenoh_result::{bail, ZResult};
23
24use crate::api::buffer::{
25 traits::{ResideInShm, ShmBuf, ShmBufIntoImmut, ShmBufMut, ShmBufUnsafeMut},
26 zshm::{zshm, ZShm},
27 zshmmut::{zshmmut, ZShmMut},
28};
29
30pub struct Typed<T, Buf> {
32 buf: Buf,
33 _phantom: PhantomData<T>,
34}
35
36impl<T, Buf: Clone> Clone for Typed<T, Buf> {
37 fn clone(&self) -> Self {
38 Self {
39 buf: self.buf.clone(),
40 _phantom: PhantomData,
41 }
42 }
43}
44
45impl<T, Buf> Typed<T, Buf> {
46 pub unsafe fn new_unchecked(buf: Buf) -> Self {
52 Self {
53 buf,
54 _phantom: PhantomData,
55 }
56 }
57
58 pub fn inner(this: &Self) -> &Buf {
60 &this.buf
61 }
62
63 pub fn inner_mut(this: &mut Self) -> &mut Buf {
65 &mut this.buf
66 }
67
68 pub fn into_inner(this: Self) -> Buf {
70 this.buf
71 }
72}
73
74impl<T, Buf> Typed<MaybeUninit<T>, Buf> {
75 pub fn new(buf: Buf) -> ZResult<Self>
78 where
79 Buf: AsRef<[u8]>,
80 {
81 let slice = buf.as_ref();
82 if slice.len() != mem::size_of::<T>() {
83 bail!(
84 "Slice length does not match type size: expected {}, got {}",
85 mem::size_of::<T>(),
86 slice.len()
87 );
88 }
89 if (slice.as_ptr() as usize) % mem::align_of::<T>() != 0 {
90 bail!(
91 "Slice alignment does not match type alignment: expected {}, got {}",
92 mem::align_of::<T>(),
93 1 << (slice.as_ptr() as usize).trailing_zeros()
94 );
95 }
96 Ok(unsafe { Self::new_unchecked(buf) })
98 }
99 pub unsafe fn assume_init(self) -> Typed<T, Buf> {
105 Typed {
106 buf: self.buf,
107 _phantom: PhantomData,
108 }
109 }
110
111 pub fn initialize(mut self, value: T) -> Typed<T, Buf>
113 where
114 Buf: ShmBufMut<[u8]>,
115 {
116 unsafe { self.buf.as_mut().as_mut_ptr().cast::<T>().write(value) };
118 unsafe { self.assume_init() }
120 }
121}
122
123impl<T> From<Typed<T, ZShmMut>> for Typed<T, ZShm> {
124 fn from(value: Typed<T, ZShmMut>) -> Self {
125 Self {
126 buf: value.buf.into(),
127 _phantom: PhantomData,
128 }
129 }
130}
131
132impl<T> TryFrom<Typed<T, ZShm>> for Typed<T, ZShmMut> {
133 type Error = Typed<T, ZShm>;
134
135 fn try_from(value: Typed<T, ZShm>) -> Result<Self, Self::Error> {
136 Ok(Self {
137 buf: value.buf.try_into().map_err(|e| Typed::<T, ZShm> {
138 buf: e,
139 _phantom: PhantomData,
140 })?,
141 _phantom: PhantomData,
142 })
143 }
144}
145
146impl<'a, T> TryFrom<Typed<T, &'a zshm>> for Typed<T, &'a zshmmut> {
147 type Error = ();
148
149 fn try_from(value: Typed<T, &'a zshm>) -> Result<Self, Self::Error> {
150 Ok(Self {
151 buf: value.buf.try_into()?,
152 _phantom: PhantomData,
153 })
154 }
155}
156
157impl<'a, T> TryFrom<Typed<T, &'a mut zshm>> for Typed<T, &'a mut zshmmut> {
158 type Error = ();
159
160 fn try_from(value: Typed<T, &'a mut zshm>) -> Result<Self, Self::Error> {
161 Ok(Self {
162 buf: value.buf.try_into()?,
163 _phantom: PhantomData,
164 })
165 }
166}
167
168impl<'a, T> TryFrom<Typed<T, &'a mut ZShm>> for Typed<T, &'a mut zshmmut> {
169 type Error = ();
170
171 fn try_from(value: Typed<T, &'a mut ZShm>) -> Result<Self, Self::Error> {
172 Ok(Self {
173 buf: value.buf.try_into()?,
174 _phantom: PhantomData,
175 })
176 }
177}
178
179impl<T> From<Typed<T, &zshmmut>> for Typed<T, &zshm> {
180 fn from(value: Typed<T, &zshmmut>) -> Self {
181 Self {
182 buf: value.buf.into(),
183 _phantom: PhantomData,
184 }
185 }
186}
187
188impl<T> From<Typed<T, &mut zshmmut>> for Typed<T, &mut zshm> {
189 fn from(value: Typed<T, &mut zshmmut>) -> Self {
190 Self {
191 buf: value.buf.into(),
192 _phantom: PhantomData,
193 }
194 }
195}
196
197impl<T: ResideInShm, Buf: ShmBuf<[u8]>> Deref for Typed<T, Buf> {
198 type Target = T;
199
200 fn deref(&self) -> &Self::Target {
201 unsafe { &*(self.buf.as_ref().as_ptr() as *const T) }
203 }
204}
205
206impl<T: ResideInShm, Buf: ShmBuf<[u8]>> AsRef<T> for Typed<T, Buf> {
207 fn as_ref(&self) -> &T {
208 self
209 }
210}
211
212impl<T: ResideInShm, Buf: ShmBufMut<[u8]>> DerefMut for Typed<T, Buf> {
213 fn deref_mut(&mut self) -> &mut Self::Target {
214 unsafe { &mut *(self.buf.as_mut().as_mut_ptr() as *mut T) }
216 }
217}
218
219impl<T: ResideInShm, Buf: ShmBufMut<[u8]>> AsMut<T> for Typed<T, Buf> {
220 fn as_mut(&mut self) -> &mut T {
221 self
222 }
223}
224
225impl<T: ResideInShm, Buf: ShmBuf<[u8]>> ShmBuf<T> for Typed<T, Buf> {
226 fn is_valid(&self) -> bool {
227 self.buf.is_valid()
228 }
229}
230
231impl<T: ResideInShm, Buf: ShmBufMut<[u8]>> ShmBufMut<T> for Typed<T, Buf> {}
232
233impl<T: ResideInShm, Buf: ShmBufUnsafeMut<[u8]>> ShmBufUnsafeMut<T> for Typed<T, Buf> {
234 unsafe fn as_mut_unchecked(&mut self) -> &mut T {
235 &mut *(self.buf.as_mut_unchecked().as_mut_ptr() as *mut T)
236 }
237}
238
239impl<T: ResideInShm, Buf: ShmBufIntoImmut<[u8]>> ShmBufIntoImmut<T> for Typed<T, Buf> {
240 type ImmutBuf = Typed<T, Buf::ImmutBuf>;
241
242 fn into_immut(self) -> Self::ImmutBuf {
243 Typed {
244 buf: self.buf.into_immut(),
245 _phantom: PhantomData,
246 }
247 }
248}