tinc 0.2.1

GRPc to REST transcoding library
use std::marker::PhantomData;

use super::Tracker;

pub trait DeserializeContent<'de>: Sized {
    type Error: serde::de::Error;

    fn deserialize<T>(self) -> Result<T, Self::Error>
    where
        T: serde::de::Deserialize<'de>,
    {
        self.deserialize_seed(PhantomData)
    }

    fn deserialize_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
    where
        T: serde::de::DeserializeSeed<'de>;
}

pub(crate) struct MapAccessValueDeserializer<'a, T> {
    pub map: &'a mut T,
    pub deserialized: &'a mut bool,
}

impl<'de, M> DeserializeContent<'de> for MapAccessValueDeserializer<'_, M>
where
    M: serde::de::MapAccess<'de>,
{
    type Error = M::Error;

    fn deserialize_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
    where
        T: serde::de::DeserializeSeed<'de>,
    {
        if *self.deserialized {
            return Err(serde::de::Error::custom(
                "invalid state: field already deserialized",
            ));
        }

        *self.deserialized = true;
        self.map.next_value_seed(seed)
    }
}

pub(crate) struct SerdeDeserializer<D> {
    pub deserializer: D,
}

impl<'de, D> DeserializeContent<'de> for SerdeDeserializer<D>
where
    D: serde::Deserializer<'de>,
{
    type Error = D::Error;

    fn deserialize_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
    where
        T: serde::de::DeserializeSeed<'de>,
    {
        seed.deserialize(self.deserializer)
    }
}

pub(crate) struct DeserializeHelper<'a, T: Tracker> {
    pub value: &'a mut T::Target,
    pub tracker: &'a mut T,
}

impl<'de, T: Tracker> serde::de::DeserializeSeed<'de> for DeserializeHelper<'_, Box<T>>
where
    for<'a> DeserializeHelper<'a, T>: serde::de::DeserializeSeed<'de, Value = ()>,
{
    type Value = ();

    fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        DeserializeHelper {
            value: self.value.as_mut(),
            tracker: self.tracker.as_mut(),
        }
        .deserialize(de)
    }
}