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)? };