# Trait serde::de::DeserializeSeed

source · [−]

    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>,
                {
                    // Decrease the number of reallocations if there are many elements
                    if let Some(size_hint) = seq.size_hint() {
                       self.0.reserve(size_hint);
                    }

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

## Required Associated Types

source

#### type Value

The type produced by using this seed.

## Required Methods

source

#### fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where
D: Deserializer<'de>,

Equivalent to the more common `Deserialize::deserialize` method, except with some initial piece of data (the seed) passed in.

## Implementations on Foreign Types

source

### impl<'de, T> DeserializeSeed<'de> for PhantomData<T> where
T: Deserialize<'de>,

#### type Value = T

source

#### fn deserialize<D>(self, deserializer: D) -> Result<T, D::Error> where
D: Deserializer<'de>,

## Implementors