rkyv_test/validation/validators/
shared.rs1use crate::{validation::SharedContext, Fallible};
4use core::{any::TypeId, fmt};
5
6#[cfg(not(feature = "std"))]
7use hashbrown::HashMap;
8#[cfg(feature = "std")]
9use std::collections::HashMap;
10
11#[derive(Debug)]
13pub enum SharedError {
14 TypeMismatch {
16 previous: TypeId,
18 current: TypeId,
20 },
21}
22
23impl fmt::Display for SharedError {
24 #[inline]
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 match self {
27 SharedError::TypeMismatch { previous, current } => write!(
28 f,
29 "the same memory region has been claimed as two different types ({:?} and {:?})",
30 previous, current
31 ),
32 }
33 }
34}
35
36#[cfg(feature = "std")]
37const _: () = {
38 use std::error::Error;
39
40 impl Error for SharedError {
41 fn source(&self) -> Option<&(dyn Error + 'static)> {
42 match self {
43 SharedError::TypeMismatch { .. } => None,
44 }
45 }
46 }
47};
48
49#[derive(Debug)]
51pub struct SharedValidator {
52 shared: HashMap<*const u8, TypeId>,
53}
54
55unsafe impl Send for SharedValidator {}
58
59unsafe impl Sync for SharedValidator {}
62
63impl SharedValidator {
64 #[inline]
66 pub fn new() -> Self {
67 Self {
68 shared: HashMap::new(),
70 }
71 }
72}
73
74impl Default for SharedValidator {
75 #[inline]
76 fn default() -> Self {
77 Self::new()
78 }
79}
80
81impl Fallible for SharedValidator {
82 type Error = SharedError;
83}
84
85impl SharedContext for SharedValidator {
86 #[inline]
87 fn register_shared_ptr(
88 &mut self,
89 ptr: *const u8,
90 type_id: TypeId,
91 ) -> Result<bool, Self::Error> {
92 if let Some(previous_type_id) = self.shared.get(&ptr) {
93 if previous_type_id != &type_id {
94 Err(SharedError::TypeMismatch {
95 previous: *previous_type_id,
96 current: type_id,
97 })
98 } else {
99 Ok(false)
100 }
101 } else {
102 self.shared.insert(ptr, type_id);
103 Ok(true)
104 }
105 }
106}