use std;
use std::collections::{BTreeMap, HashMap};
use std::marker::PhantomData;
use util::TagString;
use serde;
pub trait SeedFactory<'de, T> {
type Value;
type Seed: serde::de::DeserializeSeed<'de, Value = Self::Value>;
fn seed<E>(self, tag: T) -> Result<Self::Seed, E>
where
E: serde::de::Error;
}
impl<'de, T, V> SeedFactory<'de, T> for PhantomData<V>
where
V: serde::Deserialize<'de>,
{
type Value = V;
type Seed = PhantomData<V>;
fn seed<E>(self, _tag: T) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
Ok(PhantomData)
}
}
pub struct WithoutTag<V> {
_phantom: PhantomData<V>,
}
impl<V> WithoutTag<V> {
pub fn new() -> Self {
WithoutTag {
_phantom: PhantomData,
}
}
}
impl<V> Default for WithoutTag<V> {
fn default() -> Self {
WithoutTag::new()
}
}
impl<'de, T, V> SeedFactory<'de, T> for WithoutTag<V>
where
V: serde::Deserialize<'de>,
{
type Value = V;
type Seed = PhantomData<V>;
fn seed<E>(self, _tag: T) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
Ok(PhantomData)
}
}
pub struct WithTag<V> {
_phantom: PhantomData<V>,
}
impl<V> WithTag<V> {
pub fn new() -> Self {
WithTag {
_phantom: PhantomData,
}
}
}
impl<V> Default for WithTag<V> {
fn default() -> Self {
WithTag::new()
}
}
impl<'de, V, T> SeedFactory<'de, T> for WithTag<V>
where
V: serde::Deserialize<'de>,
{
type Value = (T, V);
type Seed = DeserializeWithTag<T, V>;
fn seed<E>(self, tag: T) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
Ok(DeserializeWithTag::new(tag))
}
}
pub struct DeserializeWithTag<T, V> {
tag: T,
_phantom: PhantomData<V>,
}
impl<T, V> DeserializeWithTag<T, V> {
pub fn new(tag: T) -> Self {
DeserializeWithTag {
tag,
_phantom: PhantomData,
}
}
}
impl<'de, T, V> serde::de::DeserializeSeed<'de> for DeserializeWithTag<T, V>
where
V: serde::Deserialize<'de>,
{
type Value = (T, V);
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok((self.tag, V::deserialize(deserializer)?))
}
}
impl<'de, V, S> SeedFactory<'de, TagString<'de>> for BTreeMap<&'static str, S>
where
S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = S;
fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.remove(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'de, V, S, H> SeedFactory<'de, TagString<'de>> for HashMap<&'static str, S, H>
where
S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = S;
fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.remove(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r mut BTreeMap<&'static str, S>
where
&'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = &'r mut S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get_mut(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r mut HashMap<&'static str, S, H>
where
&'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = &'r mut S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get_mut(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r BTreeMap<&'static str, S>
where
&'r S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = &'r S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r HashMap<&'static str, S, H>
where
&'r S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = &'r S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'de, V, S> SeedFactory<'de, TagString<'de>> for BTreeMap<String, S>
where
S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = S;
fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.remove(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'de, V, S, H> SeedFactory<'de, TagString<'de>> for HashMap<String, S, H>
where
S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = S;
fn seed<E>(mut self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.remove(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r mut BTreeMap<String, S>
where
&'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = &'r mut S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get_mut(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r mut HashMap<String, S, H>
where
&'r mut S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = &'r mut S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get_mut(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S> SeedFactory<'de, TagString<'de>> for &'r BTreeMap<String, S>
where
&'r S: serde::de::DeserializeSeed<'de, Value = V>,
{
type Value = V;
type Seed = &'r S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
impl<'r, 'de, V, S, H> SeedFactory<'de, TagString<'de>> for &'r HashMap<String, S, H>
where
&'r S: serde::de::DeserializeSeed<'de, Value = V>,
H: std::hash::BuildHasher,
{
type Value = V;
type Seed = &'r S;
fn seed<E>(self, tag: TagString<'de>) -> Result<Self::Seed, E>
where
E: serde::de::Error,
{
self.get(tag.as_ref())
.ok_or_else(|| serde::de::Error::custom("Unknown tag"))
}
}
#[cfg(feature = "erased")]
mod erased {
use erased_serde;
use serde;
pub trait FnMutSeed<V>
: for<'de> FnMut(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>
{}
impl<V, F> FnMutSeed<V> for F
where
F: for<'de> FnMut(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>,
{}
pub struct BoxFnMutSeed<V>(Box<dyn FnMutSeed<V, Output = Result<V, erased_serde::Error>> + Sync>);
impl<V> BoxFnMutSeed<V> {
pub fn new<F>(func: F) -> Self
where
F: FnMutSeed<V> + Sync + 'static,
{
BoxFnMutSeed(Box::new(func))
}
}
impl<'de, V> serde::de::DeserializeSeed<'de> for BoxFnMutSeed<V> {
type Value = V;
fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
(self.0)(&mut de).map_err(serde::de::Error::custom)
}
}
impl<'de, 'b, V> serde::de::DeserializeSeed<'de> for &'b mut BoxFnMutSeed<V> {
type Value = V;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
(self.0)(&mut de).map_err(serde::de::Error::custom)
}
}
pub trait FnSeed<V>
: for<'de> Fn(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>
{}
impl<V, F> FnSeed<V> for F
where
F: for<'de> Fn(&mut dyn erased_serde::Deserializer<'de>) -> Result<V, erased_serde::Error>,
{}
pub struct BoxFnSeed<V>(Box<dyn FnSeed<V, Output = Result<V, erased_serde::Error>> + Sync>);
impl<V> BoxFnSeed<V> {
pub fn new<F>(func: F) -> Self
where
F: FnSeed<V> + Sync + 'static,
{
BoxFnSeed(Box::new(func))
}
}
impl<'de, V> serde::de::DeserializeSeed<'de> for BoxFnSeed<V> {
type Value = V;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
(self.0)(&mut de).map_err(serde::de::Error::custom)
}
}
impl<'de, 'b, V> serde::de::DeserializeSeed<'de> for &'b BoxFnSeed<V> {
type Value = V;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
let mut de = <dyn erased_serde::Deserializer>::erase(deserializer);
(self.0)(&mut de).map_err(serde::de::Error::custom)
}
}
}
#[cfg(feature = "erased")]
pub use self::erased::{BoxFnMutSeed, BoxFnSeed, FnMutSeed, FnSeed};