Trait serde::de::DeserializeSeed
[−]
[src]
pub trait DeserializeSeed: Sized { type Value; fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer; }
DeserializeSeed
is the stateful form of the Deserialize
trait. If you
ever find yourself looking for a way to pass data into a Deserialize
impl,
this trait is the way to do it.
As one example of stateful deserialization consider deserializing a JSON
array into an existing buffer. Using the Deserialize
trait we could
deserialize a JSON array into a Vec<T>
but it would be a freshly allocated
Vec<T>
; there is no way for Deserialize
to reuse a previously allocated
buffer. Using DeserializeSeed
instead makes this possible as in the
example code below.
The canonical API for stateless deserialization looks like this:
fn func<T: Deserialize>() -> Result<T, Error>
Adjusting an API like this to support stateful deserialization is a matter of accepting a seed as input:
fn func_seed<T: DeserializeSeed>(seed: T) -> Result<T::Value, Error>
In practice the majority of deserialization is stateless. An API expecting a
seed can be appeased by passing std::marker::PhantomData
as a seed in the
case of stateless deserialization.
Example
Suppose we have JSON that looks like [[1, 2], [3, 4, 5], [6]]
and we need
to deserialize it into a flat representation like vec![1, 2, 3, 4, 5, 6]
.
Allocating a brand new Vec<T>
for each subarray would be slow. Instead we
would like to allocate a single Vec<T>
and then deserialize each subarray
into it. This requires stateful deserialization using the DeserializeSeed
trait.
// A DeserializeSeed implementation that uses stateful deserialization to // append array elements onto the end of an existing vector. The preexisting // state ("seed") in this case is the Vec<T>. The `deserialize` method of // `ExtendVec` will be traversing the inner arrays of the JSON input and // appending each integer into the existing Vec. struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>); impl<'a, T> DeserializeSeed for ExtendVec<'a, T> where T: Deserialize { // The return type of the `deserialize` method. This implementation // appends onto an existing vector but does not create any new data // structure, so the return type is (). type Value = (); fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: Deserializer { // Visitor implementation that will walk an inner array of the JSON // input. struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>); impl<'a, T> Visitor for ExtendVecVisitor<'a, T> where T: Deserialize { type Value = (); fn visit_seq<V>(self, mut visitor: V) -> Result<(), V::Error> where V: SeqVisitor { // Visit each element in the inner array and push it onto // the existing vector. while let Some(elem) = visitor.visit()? { self.0.push(elem); } Ok(()) } } deserializer.deserialize_seq(ExtendVecVisitor(self.0)) } } // Visitor implementation that will walk the outer array of the JSON input. struct FlattenedVecVisitor<T>(PhantomData<T>); impl<T> Visitor for FlattenedVecVisitor<T> where T: Deserialize { // This Visitor constructs a single Vec<T> to hold the flattened // contents of the inner arrays. type Value = Vec<T>; fn visit_seq<V>(self, mut visitor: V) -> Result<Vec<T>, V::Error> where V: SeqVisitor { // Create a single Vec to hold the flattened contents. let mut vec = Vec::new(); // Each iteration through this loop is one inner array. while let Some(()) = visitor.visit_seed(ExtendVec(&mut vec))? { // Nothing to do; inner array has been appended into `vec`. } // Return the finished vec. Ok(vec) } } let visitor = FlattenedVecVisitor(PhantomData); let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?;
Associated Types
type Value
The type produced by using this seed.
Required Methods
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where
D: Deserializer,
D: Deserializer,
Equivalent to the more common Deserialize::deserialize
method, except
with some initial piece of data (the seed) passed in.
Implementors
impl<T> DeserializeSeed for PhantomData<T> where
T: Deserialize,