1pub mod deserializers;
4
5#[cfg(feature = "alloc")]
6use crate::{ArchiveUnsized, DeserializeUnsized, Fallible};
7#[cfg(all(feature = "alloc", not(feature = "std")))]
8use ::alloc::boxed::Box;
9#[cfg(feature = "alloc")]
10use ::core::alloc::Layout;
11
12#[cfg(feature = "alloc")]
14pub trait SharedPointer {
15 fn data_address(&self) -> *const ();
17}
18
19#[cfg(feature = "alloc")]
23pub trait SharedDeserializeRegistry: Fallible {
24 fn get_shared_ptr(&mut self, ptr: *const u8) -> Option<&dyn SharedPointer>;
26
27 fn add_shared_ptr(
29 &mut self,
30 ptr: *const u8,
31 shared: Box<dyn SharedPointer>,
32 ) -> Result<(), Self::Error>;
33
34 #[inline]
37 fn deserialize_shared<T, P, F, A>(
38 &mut self,
39 value: &T::Archived,
40 to_shared: F,
41 alloc: A,
42 ) -> Result<*const T, Self::Error>
43 where
44 T: ArchiveUnsized + ?Sized,
45 P: SharedPointer + 'static,
46 F: FnOnce(*mut T) -> P,
47 A: FnMut(Layout) -> *mut u8,
48 T::Archived: DeserializeUnsized<T, Self>,
49 {
50 let ptr = value as *const T::Archived as *const u8;
51 let metadata = T::Archived::deserialize_metadata(value, self)?;
52
53 if let Some(shared_pointer) = self.get_shared_ptr(ptr) {
54 Ok(ptr_meta::from_raw_parts(
55 shared_pointer.data_address(),
56 metadata,
57 ))
58 } else {
59 let deserialized_data = unsafe { value.deserialize_unsized(self, alloc)? };
60 let shared_ptr = to_shared(ptr_meta::from_raw_parts_mut(deserialized_data, metadata));
61 let data_address = shared_ptr.data_address();
62
63 self.add_shared_ptr(ptr, Box::new(shared_ptr) as Box<dyn SharedPointer>)?;
64 Ok(ptr_meta::from_raw_parts(data_address, metadata))
65 }
66 }
67}