Skip to main content

Module wrapper

Module wrapper 

Source
Expand description

Implementations for references and wrappers.

This module provides implementations of serialization traits for (mutable) references. Moreover, it provides (de)serialization support for Box, Rc and Arc (with the std feature, or through the alloc crate in no_std builds).

While references have the obvious semantics (we serialize the referred value), wrappers are supported by erasure: if a type parameter has value Box<T>, Rc<T>, or Arc<T>, we serialize T in its place (with the exception of boxed slices and Box<str>, which have their own treatment in boxed_slice and string).

Upon deserialization, if the type parameter is T we deserialize T, but if it is Box<T>, Rc<T>, or Arc<T> we deserialize T and then wrap it in the appropriate smart pointer.

In particular, this means that it is always possible to wrap in a smart pointer type parameters, even if the serialized data did not come from a smart pointer.

Box<T>, Rc<T>, and Arc<T> implement only the (de)serialization traits, and not CopyType or TypeHash, so they cannot appear as sequence elements (e.g., Vec<Box<T>>) or as PhantomData parameters. Boxed slices and Box<str> are again the exception, having their own complete implementations.

We also provide an implementation of TypeHash for *const T, which is useful to write tuples in PhantomData with unsized type parameters, such as PhantomData<(*const T, U)> when T is unsized.

§Examples

In this example we serialize a vector wrapped in an Rc, but then we deserialize it as a plain vector, or even wrapped with an Arc:

let v = vec![1, 2, 3, 4, 5];
let mut cursor = <AlignedCursor<Aligned16>>::new();
unsafe { Rc::new(v).serialize(&mut cursor)?; }
// Rc is erased
cursor.set_position(0);
let _no_rc: Vec<i32> = unsafe { <Vec<i32>>::deserialize_full(&mut cursor)? };

// In fact, we can deserialize wrapping in any smart pointer
cursor.set_position(0);
let _no_rc_but_arc: Arc<Vec<i32>> =
    unsafe { <Arc<Vec<i32>>>::deserialize_full(&mut cursor)? };

The same is true of fields, provided that their type is a type parameter:

#[derive(Epserde)]
struct Data<A>(A);
let data = Data(Rc::new(vec![1, 2, 3, 4, 5]));
let mut cursor = <AlignedCursor<Aligned16>>::new();
unsafe { data.serialize(&mut cursor)?; }
// Rc is erased
cursor.set_position(0);
let _no_rc: Data<Vec<i32>> = unsafe { <Data<Vec<i32>>>::deserialize_full(&mut cursor)? };

// In fact, we can deserialize wrapping in any smart pointer
cursor.set_position(0);
let _no_rc_but_arc: Data<Arc<Vec<i32>>> =
    unsafe { <Data<Arc<Vec<i32>>>>::deserialize_full(&mut cursor)? };