Expand description
Blanket implementations for references and smart pointers.
This module provides blanket implementations of serialization traits for
(mutable) references. Moreover, it provides (de)serialization support for
Box, Rc and Arc if the std or alloc feature is enabled.
While references have the obvious semantics (we serialize the referred
value), smart pointers 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, which have their own
treatment).
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.
§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<A16>>::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<A16>>::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)? };