use super::Deserializer;
use crate::{Error, headers::ObjectKind};
use serde::{
de::{MapAccess, Visitor},
forward_to_deserialize_any,
};
use std::io::Read;
pub struct MapDeserializer<'a, R: Read> {
deserializer: &'a mut Deserializer<R>,
len: usize,
index: usize,
kind: ObjectKind,
}
impl<'a, R: Read> MapDeserializer<'a, R> {
pub fn new(deserializer: &'a mut Deserializer<R>, len: usize, kind: ObjectKind) -> Self {
Self {
deserializer,
len,
kind,
index: 0,
}
}
}
impl<'a, 'de, R: Read> MapAccess<'de> for MapDeserializer<'a, R> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: serde::de::DeserializeSeed<'de>,
{
if self.index == self.len {
return Ok(None);
}
seed.deserialize(self).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: serde::de::DeserializeSeed<'de>,
{
self.index += 1;
seed.deserialize(&mut *self.deserializer)
}
}
macro_rules! deserialize_key {
($fn:ident, $kind:ident, $visitor:ident, $getter:ident) => {
fn $fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
#[allow(unreachable_patterns, reason = "redundant for string keys")]
match self.kind {
ObjectKind::$kind => visitor.$visitor(self.deserializer.$getter()?),
ObjectKind::String => self.deserialize_string(visitor),
found => Err(Error::MismatchedKeyType {
expected: ObjectKind::$kind,
found,
}),
}
}
};
}
impl<'a, 'de, R: Read> serde::Deserializer<'de> for &mut MapDeserializer<'a, R> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.kind {
ObjectKind::String => self.deserialize_string(visitor),
ObjectKind::I8 => self.deserialize_i8(visitor),
ObjectKind::I16 => self.deserialize_i16(visitor),
ObjectKind::I32 => self.deserialize_i32(visitor),
ObjectKind::I64 => self.deserialize_i64(visitor),
ObjectKind::I128 => self.deserialize_i128(visitor),
ObjectKind::U8 => self.deserialize_u8(visitor),
ObjectKind::U16 => self.deserialize_u16(visitor),
ObjectKind::U32 => self.deserialize_u32(visitor),
ObjectKind::U64 => self.deserialize_u64(visitor),
ObjectKind::U128 => self.deserialize_u128(visitor),
}
}
deserialize_key!(deserialize_i8, I8, visit_i8, get_i8_value);
deserialize_key!(deserialize_i16, I16, visit_i16, get_i16_value);
deserialize_key!(deserialize_i32, I32, visit_i32, get_i32_value);
deserialize_key!(deserialize_i64, I64, visit_i64, get_i64_value);
deserialize_key!(deserialize_i128, I128, visit_i128, get_i128_value);
deserialize_key!(deserialize_u8, U8, visit_u8, get_u8_value);
deserialize_key!(deserialize_u16, U16, visit_u16, get_u16_value);
deserialize_key!(deserialize_u32, U32, visit_u32, get_u32_value);
deserialize_key!(deserialize_u64, U64, visit_u64, get_u64_value);
deserialize_key!(deserialize_u128, U128, visit_u128, get_u128_value);
deserialize_key!(deserialize_string, String, visit_string, get_string_value);
forward_to_deserialize_any! {
bool f32 f64 char str bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any
}
}