rkyv/collections/util/
validation.rs

1//! Validation implementation for utility types.
2
3use crate::{collections::util::Entry, validation::ArchiveContext};
4use ::bytecheck::CheckBytes;
5use ::core::{fmt, ptr};
6
7/// Errors that can occur while checking an archived hash map entry.
8#[derive(Debug)]
9pub enum ArchivedEntryError<K, V> {
10    /// An error occurred while checking the bytes of a key
11    KeyCheckError(K),
12    /// An error occurred while checking the bytes of a value
13    ValueCheckError(V),
14}
15
16impl<K: fmt::Display, V: fmt::Display> fmt::Display for ArchivedEntryError<K, V> {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            ArchivedEntryError::KeyCheckError(e) => write!(f, "key check error: {}", e),
20            ArchivedEntryError::ValueCheckError(e) => write!(f, "value check error: {}", e),
21        }
22    }
23}
24
25#[cfg(feature = "std")]
26const _: () = {
27    use std::error::Error;
28
29    impl<K: Error + 'static, V: Error + 'static> Error for ArchivedEntryError<K, V> {
30        fn source(&self) -> Option<&(dyn Error + 'static)> {
31            match self {
32                ArchivedEntryError::KeyCheckError(e) => Some(e as &dyn Error),
33                ArchivedEntryError::ValueCheckError(e) => Some(e as &dyn Error),
34            }
35        }
36    }
37};
38
39impl<K, V, C> CheckBytes<C> for Entry<K, V>
40where
41    K: CheckBytes<C>,
42    V: CheckBytes<C>,
43    C: ArchiveContext + ?Sized,
44{
45    type Error = ArchivedEntryError<K::Error, V::Error>;
46
47    #[inline]
48    unsafe fn check_bytes<'a>(
49        value: *const Self,
50        context: &mut C,
51    ) -> Result<&'a Self, Self::Error> {
52        K::check_bytes(ptr::addr_of!((*value).key), context)
53            .map_err(ArchivedEntryError::KeyCheckError)?;
54        V::check_bytes(ptr::addr_of!((*value).value), context)
55            .map_err(ArchivedEntryError::ValueCheckError)?;
56        Ok(&*value)
57    }
58}