use std::cmp::Ordering;
use std::collections::VecDeque;
use serde::{de, forward_to_deserialize_any};
use super::seq::{ItemKind, PairSeq};
use super::stash::{Pair, Stash};
use super::{Parser, Value};
use crate::error::{Error, Result};
pub(crate) struct PairMap<'de> {
pairs: VecDeque<Pair<'de>>,
value: Option<&'de [u8]>,
stash: Stash<'de>,
remaining_depth: u16,
}
#[derive(Copy, Clone)]
enum KeyType<'a> {
Number(u16),
Name(&'a [u8]),
None,
}
impl<'a> PartialOrd for KeyType<'a> {
fn partial_cmp(&self, other: &KeyType) -> Option<Ordering> {
if let KeyType::Number(num1) = self {
if let KeyType::Number(num2) = other {
Some(num1.cmp(num2))
} else {
Some(Ordering::Greater)
}
} else if let KeyType::Number(_) = other {
Some(Ordering::Less)
} else {
None
}
}
}
impl<'a> PartialEq for KeyType<'a> {
fn eq(&self, other: &KeyType<'a>) -> bool {
if let KeyType::Number(num1) = self {
if let KeyType::Number(num2) = other {
num1 == num2
} else {
false
}
} else if let KeyType::Name(name1) = self {
if let KeyType::Name(name2) = other {
name1 == name2
} else {
false
}
} else {
false
}
}
}
impl<'de> PairMap<'de> {
pub(crate) fn new(pairs: VecDeque<Pair<'de>>, remaining_depth: u16) -> Self {
Self {
pairs,
value: None,
stash: Stash::new(),
remaining_depth,
}
}
pub(crate) fn prepend(&mut self, mut pairs: VecDeque<Pair<'de>>) {
pairs.append(&mut self.pairs);
self.pairs = pairs;
}
pub(crate) fn parse_pair(&mut self, pair: Pair<'de>) -> Result<Option<(&'de [u8], &'de [u8])>> {
let mut key_index = 0;
let mut key_found = false;
while key_index < pair.key.len() {
match pair.key[key_index] {
b']' => {
key_found = true;
break;
}
_ => {
key_index += 1;
}
}
}
if !key_found {
return Err(Error::InvalidMapKey);
}
if pair.key.len() > key_index + 1 {
if pair.key.len() > key_index + 2 && pair.key[key_index + 1] == b'[' {
self.stash.add(
&pair.key[0..key_index],
&pair.key[(key_index + 2)..],
pair.value,
);
Ok(None)
} else {
Err(Error::InvalidMapKey)
}
} else {
Ok(Some((&pair.key[0..key_index], pair.value)))
}
}
pub(crate) fn next_key(&mut self) -> Result<Option<&'de [u8]>> {
while let Some(pair) = self.pairs.pop_back() {
match self.parse_pair(pair)? {
Some((key, value)) => {
self.value = Some(value);
return Ok(Some(key));
}
None => {
continue;
}
}
}
Ok(None)
}
pub(crate) fn next_value(&mut self) -> Result<&'de [u8]> {
match self.value.take() {
Some(value) => Ok(value),
None => Err(Error::InvalidMapValue),
}
}
pub(crate) fn into_pairs(mut self) -> Result<Vec<(&'de [u8], ItemKind<'de>)>> {
let mut values = vec![];
while let Some(pair) = self.pairs.pop_back() {
if let Some((key, value)) = self.parse_pair(pair)? {
values.push((key, ItemKind::Value(value)));
} else if let Some(key) = self.stash.next_key()? {
if key.is_empty() {
values.push((
key,
ItemKind::Map(PairMap::new(
self.stash.next_value()?,
self.remaining_depth - 1,
)),
));
} else if let Some((_, item)) = values.iter_mut().find(|item| item.0 == key) {
if let ItemKind::Map(map) = item {
map.prepend(self.stash.next_value()?)
}
} else {
values.push((
key,
ItemKind::Map(PairMap::new(
self.stash.next_value()?,
self.remaining_depth - 1,
)),
));
}
}
}
Ok(values)
}
pub(crate) fn into_seq(self) -> Result<PairSeq<'de>> {
let pairs = self.into_pairs()?;
let mut items = vec![];
for (key, value) in pairs {
if key.is_empty() {
items.push((KeyType::None, value))
} else {
let index: Result<u16> =
serde::de::Deserialize::deserialize(&mut Value::new(&mut Parser::new(key)));
if let Ok(index) = index {
items.push((KeyType::Number(index), value));
} else {
items.push((KeyType::Name(key), value));
}
}
}
items.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal));
items.reverse();
items.dedup_by(|a, b| a.0 == b.0);
let items = items.into_iter().map(|item| item.1).collect();
Ok(PairSeq::new(items))
}
}
impl<'de> de::Deserializer<'de> for PairMap<'de> {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_map(self)
}
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
if self.pairs.is_empty() {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
#[inline]
fn deserialize_enum<V>(
mut self,
_: &'static str,
_: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_enum(&mut self)
}
#[inline]
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_seq(&mut self.into_seq()?)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf unit unit_struct newtype_struct tuple
tuple_struct map struct identifier ignored_any
}
}
impl<'de> de::MapAccess<'de> for PairMap<'de> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: de::DeserializeSeed<'de>,
{
if self.remaining_depth == 0 {
return Err(Error::MaximumDepthReached);
}
if let Some(key) = self.next_key()? {
return seed
.deserialize(&mut Value::new(&mut Parser::new(key)))
.map(Some);
}
let key = self.stash.next_key()?;
match key {
Some(key) => seed
.deserialize(&mut Value::new(&mut Parser::new(key)))
.map(Some),
None => Ok(None),
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: de::DeserializeSeed<'de>,
{
match self.next_value() {
Ok(value) => seed.deserialize(&mut Value::new(&mut Parser::new(value))),
_ => {
seed.deserialize(PairMap::new(
self.stash.next_value()?,
self.remaining_depth - 1,
))
}
}
}
}
impl<'de> de::EnumAccess<'de> for &mut PairMap<'de> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
where
V: de::DeserializeSeed<'de>,
{
if self.remaining_depth == 0 {
return Err(Error::MaximumDepthReached);
}
let mut last_key = None;
while let Some(key) = self.next_key()? {
last_key = Some(key);
}
let key = match last_key {
Some(key) => key,
None => {
while let Some(key) = self.stash.next_key()? {
last_key = Some(key)
}
match last_key {
Some(key) => key,
None => {
return Err(Error::EofReached);
}
}
}
};
Ok((
seed.deserialize(&mut Value::new(&mut Parser::new(key)))?,
self,
))
}
}
impl<'de> de::VariantAccess<'de> for &mut PairMap<'de> {
type Error = Error;
#[inline]
fn unit_variant(self) -> Result<()> {
Ok(())
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.next_value() {
Ok(value) => serde::de::Deserializer::deserialize_seq(
&mut Value::new(&mut Parser::new(value)),
visitor,
),
_ => {
visitor.visit_seq(
&mut PairMap::new(self.stash.next_value()?, self.remaining_depth - 1)
.into_seq()?,
)
}
}
}
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.next_value() {
Ok(_) => Err(Error::InvalidMapValue),
_ => visitor.visit_map(PairMap::new(
self.stash.next_value()?,
self.remaining_depth - 1,
)),
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
where
T: de::DeserializeSeed<'de>,
{
match self.next_value() {
Ok(value) => seed.deserialize(&mut Value::new(&mut Parser::new(value))),
_ => seed.deserialize(PairMap::new(
self.stash.next_value()?,
self.remaining_depth - 1,
)),
}
}
}