rkyv/de/
mod.rs

1//! Deserialization traits, deserializers, and adapters.
2
3pub 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/// A deserializable shared pointer type.
13#[cfg(feature = "alloc")]
14pub trait SharedPointer {
15    /// Returns the data address for this shared pointer.
16    fn data_address(&self) -> *const ();
17}
18
19/// A registry that tracks deserialized shared memory.
20///
21/// This trait is required to deserialize shared pointers.
22#[cfg(feature = "alloc")]
23pub trait SharedDeserializeRegistry: Fallible {
24    /// Gets the data pointer of a previously-deserialized shared pointer.
25    fn get_shared_ptr(&mut self, ptr: *const u8) -> Option<&dyn SharedPointer>;
26
27    /// Adds the data address of a deserialized shared pointer to the registry.
28    fn add_shared_ptr(
29        &mut self,
30        ptr: *const u8,
31        shared: Box<dyn SharedPointer>,
32    ) -> Result<(), Self::Error>;
33
34    /// Checks whether the given reference has been deserialized and either uses the existing shared
35    /// pointer to it, or deserializes it and converts it to a shared pointer with `to_shared`.
36    #[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}