rkyv_test/impls/core/
mod.rs

1#[cfg(feature = "copy")]
2use crate::copy::ArchiveCopyOptimize;
3use crate::{
4    ser::{ScratchSpace, Serializer},
5    Archive, ArchivePointee, ArchiveUnsized, Archived, ArchivedMetadata, Deserialize,
6    DeserializeUnsized, Fallible, FixedUsize, Serialize, SerializeUnsized,
7};
8use core::{alloc::Layout, ptr, str};
9use ptr_meta::Pointee;
10
11pub mod ops;
12pub mod option;
13pub mod primitive;
14pub mod result;
15pub mod time;
16
17impl<T> ArchivePointee for T {
18    type ArchivedMetadata = ();
19
20    #[inline]
21    fn pointer_metadata(_: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata {}
22}
23
24impl<T: Archive> ArchiveUnsized for T {
25    type Archived = T::Archived;
26
27    type MetadataResolver = ();
28
29    #[inline]
30    unsafe fn resolve_metadata(
31        &self,
32        _: usize,
33        _: Self::MetadataResolver,
34        _: *mut ArchivedMetadata<Self>,
35    ) {
36    }
37}
38
39impl<T: Serialize<S>, S: Serializer + ?Sized> SerializeUnsized<S> for T {
40    #[inline]
41    fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
42        serializer.serialize_value(self)
43    }
44
45    #[inline]
46    fn serialize_metadata(&self, _: &mut S) -> Result<(), S::Error> {
47        Ok(())
48    }
49}
50
51impl<T: Archive, D: Fallible + ?Sized> DeserializeUnsized<T, D> for T::Archived
52where
53    T::Archived: Deserialize<T, D>,
54{
55    #[inline]
56    unsafe fn deserialize_unsized(
57        &self,
58        deserializer: &mut D,
59        mut alloc: impl FnMut(Layout) -> *mut u8,
60    ) -> Result<*mut (), D::Error> {
61        let deserialized = self.deserialize(deserializer)?;
62
63        let layout = Layout::new::<T>();
64        if layout.size() == 0 {
65            Ok(ptr::NonNull::<T>::dangling().as_ptr().cast())
66        } else {
67            let ptr = alloc(layout).cast::<T>();
68            assert!(!ptr.is_null());
69            ptr.write(deserialized);
70            Ok(ptr.cast())
71        }
72    }
73
74    #[inline]
75    fn deserialize_metadata(&self, _: &mut D) -> Result<<T as Pointee>::Metadata, D::Error> {
76        Ok(())
77    }
78}
79
80#[cfg(not(feature = "strict"))]
81macro_rules! peel_tuple {
82    ($type:ident $index:tt, $($type_rest:ident $index_rest:tt,)*) => { impl_tuple! { $($type_rest $index_rest,)* } };
83}
84
85#[cfg(not(feature = "strict"))]
86macro_rules! impl_tuple {
87    () => ();
88    ($($type:ident $index:tt,)+) => {
89        impl<$($type: Archive),+> Archive for ($($type,)+) {
90            type Archived = ($($type::Archived,)+);
91            type Resolver = ($($type::Resolver,)+);
92
93            #[inline]
94            unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
95                $(
96                    let (fp, fo) = out_field!(out.$index);
97                    self.$index.resolve(pos + fp, resolver.$index, fo);
98                )+
99            }
100        }
101
102        impl<$($type: Serialize<S>),+, S: Fallible + ?Sized> Serialize<S> for ($($type,)+) {
103            #[inline]
104            fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
105                let rev = ($(self.$index.serialize(serializer)?,)+);
106                Ok(($(rev.$index,)+))
107            }
108        }
109
110        impl<D: Fallible + ?Sized, $($type: Archive),+> Deserialize<($($type,)+), D> for ($($type::Archived,)+)
111        where
112            $($type::Archived: Deserialize<$type, D>,)+
113        {
114            #[inline]
115            fn deserialize(&self, deserializer: &mut D) -> Result<($($type,)+), D::Error> {
116                let rev = ($(&self.$index,)+);
117                Ok(($(rev.$index.deserialize(deserializer)?,)+))
118            }
119        }
120
121        peel_tuple! { $($type $index,)+ }
122    };
123}
124
125#[cfg(not(feature = "strict"))]
126impl_tuple! { T11 11, T10 10, T9 9, T8 8, T7 7, T6 6, T5 5, T4 4, T3 3, T2 2, T1 1, T0 0, }
127
128impl<T: Archive, const N: usize> Archive for [T; N] {
129    type Archived = [T::Archived; N];
130    type Resolver = [T::Resolver; N];
131
132    #[inline]
133    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
134        let mut resolvers = core::mem::MaybeUninit::new(resolver);
135        let resolvers_ptr = resolvers.as_mut_ptr().cast::<T::Resolver>();
136        let out_ptr = out.cast::<T::Archived>();
137        for (i, value) in self.iter().enumerate() {
138            value.resolve(
139                pos + i * core::mem::size_of::<T::Archived>(),
140                resolvers_ptr.add(i).read(),
141                out_ptr.add(i),
142            );
143        }
144    }
145}
146
147impl<T: Serialize<S>, S: Fallible + ?Sized, const N: usize> Serialize<S> for [T; N] {
148    #[inline]
149    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
150        let mut result = core::mem::MaybeUninit::<Self::Resolver>::uninit();
151        let result_ptr = result.as_mut_ptr().cast::<T::Resolver>();
152        for (i, value) in self.iter().enumerate() {
153            unsafe {
154                result_ptr.add(i).write(value.serialize(serializer)?);
155            }
156        }
157        unsafe { Ok(result.assume_init()) }
158    }
159}
160
161impl<T: Archive, D: Fallible + ?Sized, const N: usize> Deserialize<[T; N], D> for [T::Archived; N]
162where
163    T::Archived: Deserialize<T, D>,
164{
165    #[inline]
166    fn deserialize(&self, deserializer: &mut D) -> Result<[T; N], D::Error> {
167        let mut result = core::mem::MaybeUninit::<[T; N]>::uninit();
168        let result_ptr = result.as_mut_ptr().cast::<T>();
169        for (i, value) in self.iter().enumerate() {
170            unsafe {
171                result_ptr.add(i).write(value.deserialize(deserializer)?);
172            }
173        }
174        unsafe { Ok(result.assume_init()) }
175    }
176}
177
178impl<T: Archive> ArchiveUnsized for [T] {
179    type Archived = [T::Archived];
180
181    type MetadataResolver = ();
182
183    #[inline]
184    unsafe fn resolve_metadata(
185        &self,
186        _: usize,
187        _: Self::MetadataResolver,
188        out: *mut ArchivedMetadata<Self>,
189    ) {
190        out.write(to_archived!(ptr_meta::metadata(self) as FixedUsize));
191    }
192}
193
194impl<T> ArchivePointee for [T] {
195    type ArchivedMetadata = Archived<usize>;
196
197    #[inline]
198    fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata {
199        from_archived!(*archived) as usize
200    }
201}
202
203impl<T: Serialize<S>, S: ScratchSpace + Serializer + ?Sized> SerializeUnsized<S> for [T] {
204    default! {
205        fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
206            use crate::ScratchVec;
207
208            unsafe {
209                let mut resolvers = ScratchVec::new(serializer, self.len())?;
210
211                for value in self.iter() {
212                    resolvers.push(value.serialize(serializer)?);
213                }
214                let result = serializer.align_for::<T::Archived>()?;
215                for (value, resolver) in self.iter().zip(resolvers.drain(..)) {
216                    serializer.resolve_aligned(value, resolver)?;
217                }
218
219                resolvers.free(serializer)?;
220
221                Ok(result)
222            }
223        }
224    }
225
226    default! {
227        #[inline]
228        fn serialize_metadata(&self, _: &mut S) -> Result<Self::MetadataResolver, S::Error> {
229            Ok(())
230        }
231    }
232}
233
234#[cfg(feature = "copy")]
235impl<T, S> SerializeUnsized<S> for [T]
236where
237    T: Serialize<S> + crate::copy::ArchiveCopyOptimize,
238    S: ScratchSpace + Serializer + ?Sized,
239{
240    fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
241        unsafe {
242            let result = serializer.align_for::<T>()?;
243            if !self.is_empty() {
244                let bytes = core::slice::from_raw_parts(
245                    (self.as_ptr() as *const T).cast::<u8>(),
246                    self.len() * core::mem::size_of::<T>(),
247                );
248                serializer.write(bytes)?;
249            }
250            Ok(result)
251        }
252    }
253
254    #[inline]
255    fn serialize_metadata(&self, _: &mut S) -> Result<Self::MetadataResolver, S::Error> {
256        Ok(())
257    }
258}
259
260impl<T: Deserialize<U, D>, U, D: Fallible + ?Sized> DeserializeUnsized<[U], D> for [T] {
261    default! {
262        unsafe fn deserialize_unsized(&self, deserializer: &mut D, mut alloc: impl FnMut(Layout) -> *mut u8) -> Result<*mut (), D::Error> {
263            if self.is_empty() || core::mem::size_of::<U>() == 0 {
264                Ok(ptr::NonNull::<U>::dangling().as_ptr().cast())
265            } else {
266                let result = alloc(Layout::array::<U>(self.len()).unwrap()).cast::<U>();
267                assert!(!result.is_null());
268                for (i, item) in self.iter().enumerate() {
269                    result.add(i).write(item.deserialize(deserializer)?);
270                }
271                Ok(result.cast())
272            }
273        }
274    }
275
276    default! {
277        #[inline]
278        fn deserialize_metadata(&self, _: &mut D) -> Result<<[U] as Pointee>::Metadata, D::Error> {
279            Ok(ptr_meta::metadata(self))
280        }
281    }
282}
283
284#[cfg(feature = "copy")]
285impl<T, U, D> DeserializeUnsized<[U], D> for [T]
286where
287    T: Deserialize<U, D>,
288    U: ArchiveCopyOptimize,
289    D: Fallible + ?Sized,
290{
291    unsafe fn deserialize_unsized(
292        &self,
293        _: &mut D,
294        mut alloc: impl FnMut(Layout) -> *mut u8,
295    ) -> Result<*mut (), D::Error> {
296        if self.is_empty() || core::mem::size_of::<T>() == 0 {
297            Ok(ptr::NonNull::<U>::dangling().as_ptr().cast())
298        } else {
299            let result = alloc(Layout::array::<T>(self.len()).unwrap()).cast::<T>();
300            assert!(!result.is_null());
301            ptr::copy_nonoverlapping(self.as_ptr(), result, self.len());
302            Ok(result.cast())
303        }
304    }
305
306    #[inline]
307    fn deserialize_metadata(&self, _: &mut D) -> Result<<[T] as Pointee>::Metadata, D::Error> {
308        Ok(ptr_meta::metadata(self))
309    }
310}
311
312/// `str`
313
314impl ArchiveUnsized for str {
315    type Archived = str;
316
317    type MetadataResolver = ();
318
319    #[inline]
320    unsafe fn resolve_metadata(
321        &self,
322        _: usize,
323        _: Self::MetadataResolver,
324        out: *mut ArchivedMetadata<Self>,
325    ) {
326        out.write(to_archived!(ptr_meta::metadata(self) as FixedUsize))
327    }
328}
329
330impl ArchivePointee for str {
331    type ArchivedMetadata = Archived<usize>;
332
333    #[inline]
334    fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata {
335        <[u8]>::pointer_metadata(archived)
336    }
337}
338
339impl<S: Serializer + ?Sized> SerializeUnsized<S> for str {
340    #[inline]
341    fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
342        let result = serializer.pos();
343        serializer.write(self.as_bytes())?;
344        Ok(result)
345    }
346
347    #[inline]
348    fn serialize_metadata(&self, _: &mut S) -> Result<Self::MetadataResolver, S::Error> {
349        Ok(())
350    }
351}
352
353impl<D: Fallible + ?Sized> DeserializeUnsized<str, D> for <str as ArchiveUnsized>::Archived {
354    #[inline]
355    unsafe fn deserialize_unsized(
356        &self,
357        _: &mut D,
358        mut alloc: impl FnMut(Layout) -> *mut u8,
359    ) -> Result<*mut (), D::Error> {
360        if self.is_empty() {
361            Ok(ptr::null_mut())
362        } else {
363            let bytes = alloc(Layout::array::<u8>(self.len()).unwrap());
364            assert!(!bytes.is_null());
365            ptr::copy_nonoverlapping(self.as_ptr(), bytes, self.len());
366            Ok(bytes.cast())
367        }
368    }
369
370    #[inline]
371    fn deserialize_metadata(&self, _: &mut D) -> Result<<str as Pointee>::Metadata, D::Error> {
372        Ok(ptr_meta::metadata(self))
373    }
374}