#![no_std]
#![deny(missing_docs)]
use core::{convert::Infallible, marker::PhantomData, mem};
use serde::de;
pub trait SeqAccess<'de>: Sized {
type Error: de::Error;
fn next_element_seed<S>(self, seed: S) -> Result<Option<(S::Value, Self)>, Self::Error>
where
S: de::DeserializeSeed<'de>;
#[inline]
fn next_element<T>(self) -> Result<Option<(T, Self)>, Self::Error>
where
T: de::Deserialize<'de>,
{
self.next_element_seed(PhantomData)
}
#[inline]
fn size_hint(&self) -> Option<usize> {
None
}
}
pub trait MapKeyAccess<'de>: Sized {
type Error: de::Error;
type Value: MapValueAccess<'de, Error = Self::Error, Key = Self>;
#[allow(clippy::type_complexity)]
fn next_key_seed<S>(self, seed: S) -> Result<Option<(S::Value, Self::Value)>, Self::Error>
where
S: de::DeserializeSeed<'de>;
#[inline]
fn next_key<T>(self) -> Result<Option<(T, Self::Value)>, Self::Error>
where
T: de::Deserialize<'de>,
{
self.next_key_seed(PhantomData)
}
#[allow(clippy::type_complexity)]
fn next_entry_seed<K, V>(
self,
kseed: K,
vseed: V,
) -> Result<Option<((K::Value, V::Value), Option<Self>)>, Self::Error>
where
K: de::DeserializeSeed<'de>,
V: de::DeserializeSeed<'de>,
{
self.next_key_seed(kseed)?
.map(|(key, value_access)| {
value_access
.next_value_seed(vseed)
.map(|(value, key_access)| ((key, value), key_access))
})
.transpose()
}
#[inline]
#[allow(clippy::type_complexity)]
fn next_entry<K, V>(self) -> Result<Option<((K, V), Option<Self>)>, Self::Error>
where
K: de::Deserialize<'de>,
V: de::Deserialize<'de>,
Self::Value: MapValueAccess<'de, Error = Self::Error>,
{
self.next_entry_seed(PhantomData, PhantomData)
}
#[inline]
fn size_hint(&self) -> Option<usize> {
None
}
}
pub trait MapValueAccess<'de>: Sized {
type Error: de::Error;
type Key: MapKeyAccess<'de, Error = Self::Error, Value = Self>;
#[allow(clippy::type_complexity)]
fn next_value_seed<S>(self, seed: S) -> Result<(S::Value, Option<Self::Key>), Self::Error>
where
S: de::DeserializeSeed<'de>;
#[inline]
fn next_value<T>(self) -> Result<(T, Option<Self::Key>), Self::Error>
where
T: de::Deserialize<'de>,
{
self.next_value_seed(PhantomData)
}
#[inline]
fn size_hint(&self) -> Option<usize> {
None
}
}
#[derive(Debug, Clone)]
pub enum AccessAdapter<T, V> {
Ready(T),
Value(V),
Done,
}
pub type SeqAccessAdapter<T> = AccessAdapter<T, Infallible>;
impl<T, V> AccessAdapter<T, V> {
fn take(&mut self) -> Self {
mem::replace(self, AccessAdapter::Done)
}
pub fn new(access: T) -> Self {
Self::Ready(access)
}
}
impl<'de, S> de::SeqAccess<'de> for AccessAdapter<S, Infallible>
where
S: SeqAccess<'de>,
{
type Error = S::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
match self.take() {
AccessAdapter::Ready(seq) => seq.next_element_seed(seed).map(|opt| {
opt.map(|(value, seq)| {
*self = AccessAdapter::Ready(seq);
value
})
}),
AccessAdapter::Value(inf) => match inf {},
AccessAdapter::Done => Ok(None),
}
}
fn size_hint(&self) -> Option<usize> {
match *self {
AccessAdapter::Ready(ref seq) => seq.size_hint(),
AccessAdapter::Value(inf) => match inf {},
AccessAdapter::Done => Some(0),
}
}
}
impl<'de, A> de::MapAccess<'de> for AccessAdapter<A, A::Value>
where
A: MapKeyAccess<'de>,
{
type Error = A::Error;
#[inline]
fn next_key_seed<S>(&mut self, seed: S) -> Result<Option<S::Value>, Self::Error>
where
S: de::DeserializeSeed<'de>,
{
match self.take() {
AccessAdapter::Ready(access) => access.next_key_seed(seed).map(|opt| {
opt.map(|(key, value_access)| {
*self = AccessAdapter::Value(value_access);
key
})
}),
AccessAdapter::Value(_access) => panic!("called next_key_seed out of order"),
AccessAdapter::Done => Ok(None),
}
}
#[inline]
fn next_value_seed<S>(&mut self, seed: S) -> Result<S::Value, Self::Error>
where
S: de::DeserializeSeed<'de>,
{
match self.take() {
AccessAdapter::Ready(_access) => panic!("called next_value_seed out of order"),
AccessAdapter::Value(access) => {
access.next_value_seed(seed).map(|(value, key_access)| {
if let Some(key_access) = key_access {
*self = AccessAdapter::Ready(key_access)
}
value
})
}
AccessAdapter::Done => panic!("called next_value_seed out of order"),
}
}
fn next_entry_seed<K, V>(
&mut self,
key: K,
value: V,
) -> Result<Option<(K::Value, V::Value)>, Self::Error>
where
K: de::DeserializeSeed<'de>,
V: de::DeserializeSeed<'de>,
{
match self.take() {
AccessAdapter::Ready(access) => access.next_entry_seed(key, value).map(|opt| {
opt.map(|(entry, access)| {
if let Some(access) = access {
*self = AccessAdapter::Ready(access)
}
entry
})
}),
AccessAdapter::Value(_access) => panic!("called next_entry_seed out of order"),
AccessAdapter::Done => Ok(None),
}
}
#[inline]
fn size_hint(&self) -> Option<usize> {
match *self {
AccessAdapter::Ready(ref access) => access.size_hint(),
AccessAdapter::Value(ref access) => access.size_hint(),
AccessAdapter::Done => Some(0),
}
}
}
#[derive(Debug, Clone)]
pub struct SubordinateValue<V, K> {
pub value: V,
pub parent: K,
}
impl<'de, K, V> MapValueAccess<'de> for SubordinateValue<V, K>
where
V: de::Deserializer<'de>,
K: MapKeyAccess<'de, Value = Self, Error = V::Error>,
{
type Error = V::Error;
type Key = K;
fn next_value_seed<S>(self, seed: S) -> Result<(S::Value, Option<Self::Key>), Self::Error>
where
S: de::DeserializeSeed<'de>,
{
seed.deserialize(self.value)
.map(|value| (value, Some(self.parent)))
}
fn size_hint(&self) -> Option<usize> {
self.parent.size_hint()
}
}