use super::Deserializer;
use crate::{ArrayKind, Error, ObjectKind, headers::*};
use serde::{de::MapAccess, forward_to_deserialize_any};
use std::io::Read;
pub struct MatrixDeserializer<'a, R: Read> {
deserializer: &'a mut Deserializer<R>,
layout: String,
key: bool,
index: usize,
extent_type: Option<ArrayKind>,
value_type: Option<ArrayKind>,
}
impl<'a, R: Read> MatrixDeserializer<'a, R> {
pub fn new(deserializer: &'a mut Deserializer<R>, layout: String) -> Self {
Self {
deserializer,
layout,
key: false,
index: 0,
extent_type: None,
value_type: None,
}
}
}
impl<'a, 'de, R: Read> MapAccess<'de> for MatrixDeserializer<'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>,
{
match self.index {
0 => {}
1 => {
self.extent_type = Some(match self.deserializer.get_byte()? {
U8_ARRAY => ArrayKind::U8,
U16_ARRAY => ArrayKind::U16,
U32_ARRAY => ArrayKind::U32,
U64_ARRAY => ArrayKind::U64,
U128_ARRAY => ArrayKind::U128,
_ => {
return Err(Error::InvalidMatrixType);
}
})
}
2 => {
self.value_type = Some(match self.deserializer.get_byte()? {
U8_ARRAY => ArrayKind::U8,
U16_ARRAY => ArrayKind::U16,
U32_ARRAY => ArrayKind::U32,
U64_ARRAY => ArrayKind::U64,
U128_ARRAY => ArrayKind::U128,
_ => {
return Err(Error::InvalidMatrixType);
}
})
}
3 => {
return Ok(None);
}
_ => unreachable!(),
}
self.key = true;
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.key = false;
let out = seed.deserialize(&mut *self);
self.index += 1;
out
}
}
macro_rules! deserialize_number {
($fn:ident, $kind:ident, $deserializer:ident) => {
fn $fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
match self.index {
0 => Err(Error::InvalidMatrixType),
1 => {
if self.key {
Err(Error::MismatchedKeyType {
expected: ObjectKind::String,
found: ObjectKind::$kind,
})
} else {
Err(Error::InvalidMatrixType)
}
}
2 => {
if self.key {
Err(Error::MismatchedKeyType {
expected: ObjectKind::String,
found: ObjectKind::$kind,
})
} else {
match self.value_type.unwrap() {
ArrayKind::$kind => self.deserializer.$deserializer(visitor),
found => Err(Error::MismatchedElementType {
expected: ArrayKind::$kind,
found,
}),
}
}
}
_ => unreachable!(),
}
}
};
}
impl<'a, 'de, R: Read> serde::Deserializer<'de> for &mut MatrixDeserializer<'a, R> {
type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
Err(Error::InvalidMatrixType)
}
deserialize_number!(deserialize_i8, I8, deserialize_i8_array);
deserialize_number!(deserialize_i16, I16, deserialize_i16_array);
deserialize_number!(deserialize_i32, I32, deserialize_i32_array);
deserialize_number!(deserialize_i64, I64, deserialize_i64_array);
deserialize_number!(deserialize_i128, I128, deserialize_i128_array);
deserialize_number!(deserialize_u8, U8, deserialize_u8_array);
deserialize_number!(deserialize_u16, U16, deserialize_u16_array);
deserialize_number!(deserialize_u32, U32, deserialize_u32_array);
deserialize_number!(deserialize_u64, U64, deserialize_u64_array);
deserialize_number!(deserialize_u128, U128, deserialize_u128_array);
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
match self.index {
0 => Err(Error::InvalidMatrixType),
1 => {
if self.key {
Err(Error::InvalidKey)
} else {
Err(Error::InvalidMatrixType)
}
}
2 => {
if self.key {
Err(Error::InvalidKey)
} else {
match self.value_type.unwrap() {
ArrayKind::F32 => self.deserializer.deserialize_f32_array(visitor),
found => Err(Error::MismatchedElementType {
expected: ArrayKind::F32,
found,
}),
}
}
}
_ => unreachable!(),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
match self.index {
0 => Err(Error::InvalidMatrixType),
1 => {
if self.key {
Err(Error::InvalidKey)
} else {
Err(Error::InvalidMatrixType)
}
}
2 => {
if self.key {
Err(Error::InvalidKey)
} else {
match self.value_type.unwrap() {
ArrayKind::F64 => self.deserializer.deserialize_f64_array(visitor),
found => Err(Error::MismatchedElementType {
expected: ArrayKind::F64,
found,
}),
}
}
}
_ => unreachable!(),
}
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
match self.index {
0 => {
if self.key {
visitor.visit_str("layout")
} else {
visitor.visit_str(&self.layout)
}
}
1 => {
if self.key {
visitor.visit_str("extents")
} else {
Err(Error::MismatchedElementType {
expected: self.extent_type.unwrap(),
found: ArrayKind::String,
})
}
}
2 => {
if self.key {
visitor.visit_str("value")
} else {
Err(Error::MismatchedElementType {
expected: self.value_type.unwrap(),
found: ArrayKind::String,
})
}
}
_ => unreachable!(),
}
}
forward_to_deserialize_any! {
bool char bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any
}
}