Trait serde::de::DeserializeSeed [−][src]
pub trait DeserializeSeed<'de>: Sized { type Value; fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>; }
Expand description
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<'de, T: Deserialize<'de>>() -> Result<T, Error>
Adjusting an API like this to support stateful deserialization is a matter of accepting a seed as input:
fn func_seed<'de, T: DeserializeSeed<'de>>(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.
Lifetime
The 'de
lifetime of this trait is the lifetime of data that may be
borrowed by Self::Value
when deserialized. See the page Understanding
deserializer lifetimes for a more detailed explanation of these lifetimes.
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.
use std::fmt; use std::marker::PhantomData; use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; // 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<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> where T: Deserialize<'de>, { // 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<'de>, { // Visitor implementation that will walk an inner array of the JSON // input. struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>); impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> where T: Deserialize<'de>, { type Value = (); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an array of integers") } fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error> where A: SeqAccess<'de>, { // Visit each element in the inner array and push it onto // the existing vector. while let Some(elem) = seq.next_element()? { 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<'de, T> Visitor<'de> for FlattenedVecVisitor<T> where T: Deserialize<'de>, { // This Visitor constructs a single Vec<T> to hold the flattened // contents of the inner arrays. type Value = Vec<T>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "an array of arrays") } fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error> where A: SeqAccess<'de>, { // 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(()) = seq.next_element_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
Required methods
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where
D: Deserializer<'de>,
[src]
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where
D: Deserializer<'de>,
[src]Equivalent to the more common Deserialize::deserialize
method, except
with some initial piece of data (the seed) passed in.