rkyv/de/deserializers/
alloc.rs1use crate::{
4 de::{SharedDeserializeRegistry, SharedPointer},
5 Fallible,
6};
7#[cfg(not(feature = "std"))]
8use alloc::boxed::Box;
9use core::fmt;
10#[cfg(not(feature = "std"))]
11use hashbrown::hash_map;
12#[cfg(feature = "std")]
13use std::collections::hash_map;
14
15#[derive(Debug)]
17pub enum SharedDeserializeMapError {
18 DuplicateSharedPointer(*const u8),
20}
21
22unsafe impl Send for SharedDeserializeMapError {}
25
26unsafe impl Sync for SharedDeserializeMapError {}
29
30impl fmt::Display for SharedDeserializeMapError {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 match self {
33 Self::DuplicateSharedPointer(p) => write!(f, "duplicate shared pointer: {:p}", p),
34 }
35 }
36}
37
38#[cfg(feature = "std")]
39const _: () = {
40 use std::error::Error;
41
42 impl Error for SharedDeserializeMapError {}
43};
44
45pub struct SharedDeserializeMap {
47 shared_pointers: hash_map::HashMap<*const u8, Box<dyn SharedPointer>>,
48}
49
50impl SharedDeserializeMap {
51 #[inline]
53 pub fn new() -> Self {
54 Self {
55 shared_pointers: hash_map::HashMap::new(),
56 }
57 }
58
59 #[inline]
61 pub fn with_capacity(capacity: usize) -> Self {
62 Self {
63 shared_pointers: hash_map::HashMap::with_capacity(capacity),
64 }
65 }
66}
67
68impl fmt::Debug for SharedDeserializeMap {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.debug_map()
71 .entries(
72 self.shared_pointers
73 .iter()
74 .map(|(s, p)| (s, &**p as *const _)),
75 )
76 .finish()
77 }
78}
79
80impl Default for SharedDeserializeMap {
81 #[inline]
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87impl Fallible for SharedDeserializeMap {
88 type Error = SharedDeserializeMapError;
89}
90
91impl SharedDeserializeRegistry for SharedDeserializeMap {
92 fn get_shared_ptr(&mut self, ptr: *const u8) -> Option<&dyn SharedPointer> {
93 self.shared_pointers.get(&ptr).map(|p| p.as_ref())
94 }
95
96 fn add_shared_ptr(
97 &mut self,
98 ptr: *const u8,
99 shared: Box<dyn SharedPointer>,
100 ) -> Result<(), Self::Error> {
101 match self.shared_pointers.entry(ptr) {
102 hash_map::Entry::Occupied(_) => {
103 Err(SharedDeserializeMapError::DuplicateSharedPointer(ptr))
104 }
105 hash_map::Entry::Vacant(e) => {
106 e.insert(shared);
107 Ok(())
108 }
109 }
110 }
111}