use alloc::vec::Vec;
use crate::deserialize::adapter::deserialize::Deserializer;
use crate::deserialize::Item;
use crate::DeserializeError;
use nom::Input;
use serde_core::de::{DeserializeSeed, MapAccess};
use core::cell::Cell;
use core::fmt::{Debug, Display};
use core::marker::PhantomData;
use nom::error::ErrorKind;
pub struct MapDeserializer<I: Input + Debug + Display, R: Iterator<Item = Item>> {
pub items: R,
pub next_value: Cell<Option<Vec<Item>>>,
pub phantom_data: PhantomData<I>,
pub size: usize
}
impl<'de, I: Input + Debug + Display, R: Iterator<Item = Item>> MapAccess<'de> for MapDeserializer<I, R> {
type Error = DeserializeError<I>;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeSeed<'de>
{
match self.items.next() {
None => Ok(None),
Some(next) => {
match next {
Item::AnnotatedList(item) => {
self.next_value.set(Some(item.1));
seed.deserialize(&mut Deserializer::from_item(*item.0)).map(Some)
}
_ => Err(DeserializeError::ExpectedAnnotatedList)
}
}
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeSeed<'de>
{
match self.next_value.take() {
None => Err(DeserializeError::ParseError(None, ErrorKind::Eof)),
Some(list) =>
if list.len() == 1 {
match list.into_iter().next() {
None => Err(DeserializeError::ParseError(None, ErrorKind::Eof)),
Some(item) => seed.deserialize(&mut Deserializer::from_item(item))
}
} else {
seed.deserialize(&mut Deserializer::from_item(Item::List(list)))
}
}
}
fn next_entry_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>, Self::Error>
where
K: DeserializeSeed<'de>,
V: DeserializeSeed<'de>,
{
match self.next_value.get_mut() {
None => {
match self.items.next() {
None => Ok(None),
Some(next) => {
match next {
Item::AnnotatedList(item) => {
Ok(Some((
kseed.deserialize(&mut Deserializer::from_item(*item.0))?,
vseed.deserialize(&mut Deserializer::new(item.1.into_iter()))?
)))
}
_ => Err(DeserializeError::ExpectedAnnotatedList)
}
}
}
}
Some(_) => Err(DeserializeError::OutOfOrder)
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.size)
}
}