Example
// A Visitor is a type that holds methods that a Deserializer can drive
// depending on what is contained in the input data.
//
// In the case of a map we need generic type parameters K and V to be
// able to set the output type correctly, but don't require any state.
// This is an example of a "zero sized type" in Rust. The PhantomData
// keeps the compiler from complaining about unused generic type
// parameters.
struct MyMapVisitor<K, V> {
marker: PhantomData<MyMap<K, V>>
}
impl<K, V> MyMapVisitor<K, V> {
fn new() -> Self {
MyMapVisitor {
marker: PhantomData
}
}
}
// This is the trait that Deserializers are going to be driving. There
// is one method for each type of data that our type knows how to
// deserialize from. There are many other methods that are not
// implemented here, for example deserializing from integers or strings.
// By default those methods will return an error, which makes sense
// because we cannot deserialize a MyMap from an integer or string.
impl<K, V> de::Visitor for MyMapVisitor<K, V>
where K: Deserialize,
V: Deserialize
{
// The type that our Visitor is going to produce.
type Value = MyMap<K, V>;
// Deserialize MyMap from an abstract "map" provided by the
// Deserializer. The MapVisitor input is a callback provided by
// the Deserializer to let us see each entry in the map.
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
where M: de::MapVisitor
{
let mut values = MyMap::with_capacity(visitor.size_hint().0);
// While there are entries remaining in the input, add them
// into our map.
while let Some((key, value)) = visitor.visit()? {
values.insert(key, value);
}
Ok(values)
}
// As a convenience, provide a way to deserialize MyMap from
// the abstract "unit" type. This corresponds to `null` in JSON.
// If your JSON contains `null` for a field that is supposed to
// be a MyMap, we interpret that as an empty map.
fn visit_unit<E>(self) -> Result<Self::Value, E>
where E: de::Error
{
Ok(MyMap::new())
}
// When an unexpected data type is encountered, this method will
// be invoked to inform the user what is actually expected.
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map or `null`")
}
}
// This is the trait that informs Serde how to deserialize MyMap.
impl<K, V> Deserialize for MyMap<K, V>
where K: Deserialize,
V: Deserialize
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer
{
// Instantiate our Visitor and ask the Deserializer to drive
// it over the input data, resulting in an instance of MyMap.
deserializer.deserialize_map(MyMapVisitor::new())
}
}