vector_buffers/variants/disk_v2/
ser.rs

1use std::fmt;
2
3use bytecheck::CheckBytes;
4use rkyv::{
5    check_archived_root,
6    validation::{validators::DefaultValidator, CheckArchiveError},
7    Archive,
8};
9
10/// Error that occurred during serialization.
11#[derive(Debug)]
12pub enum SerializeError<T> {
13    /// The type failed to be serialized correctly.
14    FailedToSerialize(String),
15
16    /// The backing store was not big enough to fit the serialized version of the value.
17    ///
18    /// The original value that was given is returned, along with the minimum size that the backing
19    /// store must be sized to hold the serialized value.  Providing a backing store that is larger
20    /// than the given value is acceptable, but not necessary.
21    BackingStoreTooSmall(T, usize),
22}
23
24/// Error that occurred during deserialization.
25#[derive(Debug)]
26pub enum DeserializeError {
27    /// The data in the backing store does not represent the archive type as whole.
28    ///
29    /// This error is primarily indicative of not having enough data present, which is often a
30    /// signal that the type represented by the bytes in the backing store and the incoming archive
31    /// type are either entirely different, or that the structure of the type has changed: addition
32    /// or removal of fields, reordering of fields, etc.
33    ///
34    /// The backing store that was given is returned, along with an error string that briefly
35    /// describes the error in a more verbose fashion, suitable for debugging.
36    InvalidStructure(String),
37
38    /// Some of the data in the backing store cannot represent a particular field in the archive type.
39    ///
40    /// This would typically occur if the data read for a particular field could not specifically
41    /// represent that type.  For example, a boolean is encoded as a single byte with a 0 or 1 as
42    /// the value, so a value between 2 and 255 is inherently invalid for representing a boolean.
43    ///
44    /// This can be a subtle difference from `InvalidStructure`, but is primarily indicative of
45    /// in-place data corruption, or data being overwritten by an outside process.
46    ///
47    /// The backing store that was given is returned, along with an error string that briefly
48    /// describes the error in a more verbose fashion, suitable for debugging.
49    InvalidData(String),
50}
51
52impl DeserializeError {
53    /// Consumes this error and returns the stringified error reason.
54    pub fn into_inner(self) -> String {
55        match self {
56            DeserializeError::InvalidData(s) => format!("invalid data: {s}"),
57            DeserializeError::InvalidStructure(s) => format!("invalid structure: {s}"),
58        }
59    }
60}
61
62impl<T, C> From<CheckArchiveError<T, C>> for DeserializeError
63where
64    T: fmt::Display,
65    C: fmt::Display,
66{
67    fn from(e: CheckArchiveError<T, C>) -> Self {
68        match e {
69            CheckArchiveError::ContextError(ce) => {
70                DeserializeError::InvalidStructure(ce.to_string())
71            }
72            CheckArchiveError::CheckBytesError(cbe) => {
73                DeserializeError::InvalidData(cbe.to_string())
74            }
75        }
76    }
77}
78
79/// Tries to deserialize the given buffer as the archival type `T`.
80///
81/// The archived type is assumed to exist starting at index 0 of the buffer.  Additionally, the
82/// archived value is checked for data conformance.
83///
84/// # Errors
85///
86/// If the buffer does not contained an archived `T`, or there was an issue with too little data, or
87/// invalid values, etc, then an error variant will be emitted.  The error will describe the
88/// high-level error, as well as provide a string with a more verbose explanation of the error.
89pub fn try_as_archive<'a, T>(buf: &'a [u8]) -> Result<&'a T::Archived, DeserializeError>
90where
91    T: Archive,
92    T::Archived: for<'b> CheckBytes<DefaultValidator<'b>>,
93{
94    debug_assert!(!buf.is_empty());
95    check_archived_root::<T>(buf).map_err(Into::into)
96}