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}