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