serde-beve 1.0.0

A BEVE data format for Serde
Documentation
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
    }
}