use de::seed::SeedFactory;
use std::fmt;
use std::marker::PhantomData;
use serde;
pub fn deserialize<'de, T, D, F>(deserializer: D, seed_factory: F) -> Result<F::Value, D::Error>
where
T: serde::Deserialize<'de>,
D: serde::Deserializer<'de>,
F: SeedFactory<'de, T>,
{
deserialize_seed(deserializer, seed_factory, PhantomData::<T>)
}
pub fn deserialize_seed<'de, D, F, S>(
deserializer: D,
seed_factory: F,
tag_seed: S,
) -> Result<F::Value, D::Error>
where
D: serde::Deserializer<'de>,
F: SeedFactory<'de, S::Value>,
S: serde::de::DeserializeSeed<'de>,
{
deserializer.deserialize_map(Visitor::new(seed_factory, tag_seed))
}
pub struct Visitor<F, S> {
seed_factory: F,
tag_seed: S,
}
impl<F, S> Visitor<F, S> {
pub fn new(seed_factory: F, tag_seed: S) -> Self {
Visitor {
seed_factory,
tag_seed,
}
}
}
impl<'de, F, S> serde::de::Visitor<'de> for Visitor<F, S>
where
F: SeedFactory<'de, S::Value>,
S: serde::de::DeserializeSeed<'de>,
{
type Value = F::Value;
fn expecting(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
write!(fmtr, "a map with exactly one entry")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
use serde::de::Error;
match map.size_hint() {
Some(n) if n != 1 => Err(serde::de::Error::invalid_length(n, &self))?,
_ => {},
}
let tag = map.next_key_seed(self.tag_seed)?
.ok_or_else(|| Error::invalid_length(0, &"a map with exactly one entry"))?;
map.next_value_seed(self.seed_factory.seed(tag)?)
}
}