Skip to main content

rkyv/validation/
mod.rs

1//! Validation implementations and helper types.
2
3pub mod archive;
4pub mod shared;
5
6use core::{any::TypeId, ops::Range};
7
8pub use self::{
9    archive::{ArchiveContext, ArchiveContextExt},
10    shared::SharedContext,
11};
12use crate::erased::{ErasedPtr, Metadata};
13
14/// The default validator.
15#[derive(Debug)]
16pub struct Validator<A, S> {
17    archive: A,
18    shared: S,
19}
20
21impl<A, S> Validator<A, S> {
22    /// Creates a new validator from a byte range.
23    #[inline]
24    pub fn new(archive: A, shared: S) -> Self {
25        Self { archive, shared }
26    }
27}
28
29unsafe impl<A, S, E> ArchiveContext<E> for Validator<A, S>
30where
31    A: ArchiveContext<E>,
32{
33    fn check_subtree_ptr(
34        &mut self,
35        ptr: *const u8,
36        layout: &core::alloc::Layout,
37    ) -> Result<(), E> {
38        self.archive.check_subtree_ptr(ptr, layout)
39    }
40
41    unsafe fn push_subtree_range(
42        &mut self,
43        root: *const u8,
44        end: *const u8,
45    ) -> Result<Range<usize>, E> {
46        // SAFETY: This just forwards the call to the underlying `CoreValidator`
47        // which has the same safety requirements.
48        unsafe { self.archive.push_subtree_range(root, end) }
49    }
50
51    unsafe fn pop_subtree_range(
52        &mut self,
53        range: Range<usize>,
54    ) -> Result<(), E> {
55        // SAFETY: This just forwards the call to the underlying `CoreValidator`
56        // which has the same safety requirements.
57        unsafe { self.archive.pop_subtree_range(range) }
58    }
59}
60
61impl<A, S, E> SharedContext<E> for Validator<A, S>
62where
63    S: SharedContext<E>,
64{
65    fn start_shared(
66        &mut self,
67        shared_type_id: TypeId,
68        ptr: ErasedPtr,
69        metadata_is_eq: unsafe fn(Metadata, Metadata) -> bool,
70    ) -> Result<shared::ValidationState, E> {
71        self.shared
72            .start_shared(shared_type_id, ptr, metadata_is_eq)
73    }
74
75    fn finish_shared(
76        &mut self,
77        shared_type_id: TypeId,
78        ptr: ErasedPtr,
79    ) -> Result<(), E> {
80        self.shared.finish_shared(shared_type_id, ptr)
81    }
82}