1pub mod serializers;
4
5use crate::{Archive, ArchiveUnsized, Fallible, RelPtr, Serialize, SerializeUnsized};
6use core::{alloc::Layout, mem, ptr::NonNull, slice};
7
8pub trait Serializer: Fallible {
17    fn pos(&self) -> usize;
19
20    fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error>;
22
23    #[inline]
25    fn pad(&mut self, padding: usize) -> Result<(), Self::Error> {
26        const MAX_ZEROES: usize = 32;
27        const ZEROES: [u8; MAX_ZEROES] = [0; MAX_ZEROES];
28        debug_assert!(padding < MAX_ZEROES);
29
30        self.write(&ZEROES[0..padding])
31    }
32
33    #[inline]
35    fn align(&mut self, align: usize) -> Result<usize, Self::Error> {
36        let mask = align - 1;
37        debug_assert_eq!(align & mask, 0);
38
39        self.pad((align - (self.pos() & mask)) & mask)?;
40        Ok(self.pos())
41    }
42
43    #[inline]
45    fn align_for<T>(&mut self) -> Result<usize, Self::Error> {
46        self.align(mem::align_of::<T>())
47    }
48
49    unsafe fn resolve_aligned<T: Archive + ?Sized>(
58        &mut self,
59        value: &T,
60        resolver: T::Resolver,
61    ) -> Result<usize, Self::Error> {
62        let pos = self.pos();
63        debug_assert_eq!(pos & (mem::align_of::<T::Archived>() - 1), 0);
64
65        let mut resolved = mem::MaybeUninit::<T::Archived>::uninit();
66        resolved.as_mut_ptr().write_bytes(0, 1);
67        value.resolve(pos, resolver, resolved.as_mut_ptr());
68
69        let data = resolved.as_ptr().cast::<u8>();
70        let len = mem::size_of::<T::Archived>();
71        self.write(slice::from_raw_parts(data, len))?;
72        Ok(pos)
73    }
74
75    #[inline]
77    fn serialize_value<T: Serialize<Self>>(&mut self, value: &T) -> Result<usize, Self::Error> {
78        let resolver = value.serialize(self)?;
79        self.align_for::<T::Archived>()?;
80        unsafe { self.resolve_aligned(value, resolver) }
81    }
82
83    unsafe fn resolve_unsized_aligned<T: ArchiveUnsized + ?Sized>(
93        &mut self,
94        value: &T,
95        to: usize,
96        metadata_resolver: T::MetadataResolver,
97    ) -> Result<usize, Self::Error> {
98        let from = self.pos();
99        debug_assert_eq!(from & (mem::align_of::<RelPtr<T::Archived>>() - 1), 0);
100
101        let mut resolved = mem::MaybeUninit::<RelPtr<T::Archived>>::uninit();
102        resolved.as_mut_ptr().write_bytes(0, 1);
103        value.resolve_unsized(from, to, metadata_resolver, resolved.as_mut_ptr());
104
105        let data = resolved.as_ptr().cast::<u8>();
106        let len = mem::size_of::<RelPtr<T::Archived>>();
107        self.write(slice::from_raw_parts(data, len))?;
108        Ok(from)
109    }
110
111    #[inline]
113    fn serialize_unsized_value<T: SerializeUnsized<Self> + ?Sized>(
114        &mut self,
115        value: &T,
116    ) -> Result<usize, Self::Error> {
117        let to = value.serialize_unsized(self)?;
118        let metadata_resolver = value.serialize_metadata(self)?;
119        self.align_for::<RelPtr<T::Archived>>()?;
120        unsafe { self.resolve_unsized_aligned(value, to, metadata_resolver) }
121    }
122}
123
124pub trait ScratchSpace: Fallible {
128    unsafe fn push_scratch(&mut self, layout: Layout) -> Result<NonNull<[u8]>, Self::Error>;
134
135    unsafe fn pop_scratch(&mut self, ptr: NonNull<u8>, layout: Layout) -> Result<(), Self::Error>;
142}
143
144pub trait SharedSerializeRegistry: Fallible {
148    fn get_shared_ptr(&self, value: *const u8) -> Option<usize>;
152
153    #[inline]
157    fn get_shared<T: ?Sized>(&self, value: &T) -> Option<usize> {
158        self.get_shared_ptr(value as *const T as *const u8)
159    }
160
161    fn add_shared_ptr(&mut self, value: *const u8, pos: usize) -> Result<(), Self::Error>;
163
164    #[inline]
166    fn add_shared<T: ?Sized>(&mut self, value: &T, pos: usize) -> Result<(), Self::Error> {
167        self.add_shared_ptr(value as *const T as *const u8, pos)
168    }
169
170    #[inline]
173    fn serialize_shared<T: SerializeUnsized<Self> + ?Sized>(
174        &mut self,
175        value: &T,
176    ) -> Result<usize, Self::Error>
177    where
178        Self: Serializer,
179    {
180        if let Some(pos) = self.get_shared(value) {
181            Ok(pos)
182        } else {
183            let pos = value.serialize_unsized(self)?;
184            self.add_shared(value, pos)?;
185            Ok(pos)
186        }
187    }
188}