Skip to main content

rspack_cacheable/
deserialize.rs

1use rkyv::{
2  Archive, Deserialize, access,
3  api::{deserialize_using, high::HighValidator},
4  bytecheck::CheckBytes,
5  de::Pool,
6  rancor::Strategy,
7  util::AlignedVec,
8};
9
10use crate::{
11  context::{CacheableContext, ContextGuard},
12  error::{Error, Result},
13};
14
15pub type Validator<'a> = HighValidator<'a, Error>;
16pub type Deserializer = Strategy<Pool, Error>;
17
18/// Transform bytes to struct
19///
20/// This function implementation refers to rkyv::from_bytes and
21/// add custom error and context support
22pub fn from_bytes<T, C: CacheableContext>(bytes: &[u8], context: &C) -> Result<T>
23where
24  T: Archive,
25  T::Archived: for<'a> CheckBytes<Validator<'a>> + Deserialize<T, Deserializer>,
26{
27  let guard = ContextGuard::new(context);
28  let mut deserializer = Pool::default();
29  guard.add_to_pooling(&mut deserializer)?;
30  // The `bytes` ptr address in miri will throw UnalignedPointer error in rkyv.
31  // AlignedVec will force aligned the ptr address.
32  // Refer code: https://github.com/rkyv/rkyv/blob/dabbc1fcf5052f141403b84493bddb74c44f9ba9/rkyv/src/validation/archive/validator.rs#L135
33  let mut aligned_vec = AlignedVec::<16>::new();
34  aligned_vec.extend_from_slice(bytes);
35  deserialize_using(
36    access::<T::Archived, Error>(&aligned_vec)?,
37    &mut deserializer,
38  )
39}