serde-smile 0.1.2

A Smile implementation for Serde
Documentation
use crate::de::read::Buf;
use crate::de::{zigzag_i32, Read};
use crate::value::BigDecimal;
use crate::{Deserializer, Error};
use serde::de::value::BorrowedStrDeserializer;
use serde::de::{DeserializeSeed, MapAccess, Visitor};
use serde::forward_to_deserialize_any;

#[derive(Copy, Clone)]
pub(crate) enum Stage {
    Scale,
    Buf,
}

pub(crate) struct BigDecimalDeserializer<'a, 'de, R> {
    pub(crate) de: &'a mut Deserializer<'de, R>,
    pub(crate) stage: Option<Stage>,
}

impl<'de, R> MapAccess<'de> for BigDecimalDeserializer<'_, 'de, R>
where
    R: Read<'de>,
{
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
    where
        K: DeserializeSeed<'de>,
    {
        match self.stage {
            Some(Stage::Scale) => seed
                .deserialize(BorrowedStrDeserializer::new(BigDecimal::SCALE_FIELD_NAME))
                .map(Some),
            Some(Stage::Buf) => seed
                .deserialize(BorrowedStrDeserializer::new(BigDecimal::VALUE_FIELD_NAME))
                .map(Some),
            None => Ok(None),
        }
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
    where
        V: DeserializeSeed<'de>,
    {
        match self.stage {
            Some(Stage::Scale) => {
                self.stage = Some(Stage::Buf);
                seed.deserialize(BigDecimalValueDeserializer {
                    de: &mut *self.de,
                    stage: Stage::Scale,
                })
            }
            Some(Stage::Buf) => {
                self.stage = None;
                seed.deserialize(BigDecimalValueDeserializer {
                    de: &mut *self.de,
                    stage: Stage::Buf,
                })
            }
            None => panic!("next_value_seed called after end"),
        }
    }
}

struct BigDecimalValueDeserializer<'a, 'de, R> {
    de: &'a mut Deserializer<'de, R>,
    stage: Stage,
}

impl<'de, R> serde::Deserializer<'de> for BigDecimalValueDeserializer<'_, 'de, R>
where
    R: Read<'de>,
{
    type Error = Error;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        match self.stage {
            Stage::Scale => {
                let scale = self.de.parse_vint(5)?;
                let scale = zigzag_i32(scale as u32);
                visitor.visit_i32(scale)
            }
            Stage::Buf => {
                let buf = self.de.parse_7_bit_binary()?;
                match buf {
                    Buf::Short(buf) => visitor.visit_bytes(buf),
                    Buf::Long(buf) => visitor.visit_borrowed_bytes(buf),
                }
            }
        }
    }

    forward_to_deserialize_any! {
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
        bytes byte_buf option unit unit_struct newtype_struct seq tuple
        tuple_struct map struct enum identifier ignored_any
    }
}