serde-smile 0.3.0

A Smile implementation for Serde
Documentation
use crate::de::read::Buf;
use crate::de::{Deserializer, Read};
use crate::Error;
use serde::de::{self, Visitor};
use serde::{forward_to_deserialize_any, serde_if_integer128};
use std::borrow::Cow;
use std::ops::Deref;
use std::str;

pub(crate) struct KeyDeserializer<'a, 'de, R> {
    pub(crate) de: &'a mut Deserializer<'de, R>,
}

impl<'de, R> KeyDeserializer<'_, 'de, R>
where
    R: Read<'de>,
{
    fn parse_shared_str<'a>(&'a mut self, reference: u16) -> Result<Str<'a, 'de>, Error> {
        let cow = self
            .de
            .shared_properties
            .as_ref()
            .and_then(|c| c.get(reference))
            .ok_or_else(Error::invalid_string_reference)?;

        let s = match cow {
            Cow::Borrowed(s) => Str::Long(s),
            Cow::Owned(s) => Str::Short(s),
        };

        Ok(s)
    }

    fn parse_long_shared_str<'a>(&'a mut self, reference_hi: u8) -> Result<Str<'a, 'de>, Error> {
        let reference_lo = self.de.parse_u8()?;
        let reference = (reference_hi as u16) << 8 | reference_lo as u16;
        self.parse_shared_str(reference)
    }

    fn parse_str_inner<'a, F>(&'a mut self, f: F) -> Result<Str<'a, 'de>, Error>
    where
        F: FnOnce(&'a mut R) -> Result<Option<Buf<'a, 'de>>, Error>,
    {
        let buf = f(&mut self.de.reader)?.ok_or_else(Error::eof_while_parsing_value)?;

        match buf {
            Buf::Short(buf) => {
                let s = str::from_utf8(buf).map_err(|_| Error::invalid_utf8())?;
                if let Some(shared_properties) = &mut self.de.shared_properties {
                    shared_properties.intern(Cow::Owned(s.to_string()));
                }

                Ok(Str::Short(s))
            }
            Buf::Long(buf) => {
                let s = str::from_utf8(buf).map_err(|_| Error::invalid_utf8())?;
                if let Some(shared_properties) = &mut self.de.shared_properties {
                    shared_properties.intern(Cow::Borrowed(s));
                }

                Ok(Str::Long(s))
            }
        }
    }

    fn parse_long_str<'a>(&'a mut self) -> Result<Str<'a, 'de>, Error> {
        self.parse_str_inner(|r| r.read_until(0xfc))
    }

    fn parse_short_str<'a>(&'a mut self, len: usize) -> Result<Str<'a, 'de>, Error> {
        self.parse_str_inner(|r| r.read(len))
    }

    fn parse_str<'a>(&'a mut self) -> Result<Str<'a, 'de>, Error> {
        match self.de.parse_u8()? {
            0x00..=0x1f => Err(Error::reserved_token()),
            0x20 => Ok(Str::Long("")),
            0x21..=0x2f => Err(Error::reserved_token()),
            token @ 0x30..=0x33 => self.parse_long_shared_str(token - 0x30),
            0x34 => self.parse_long_str(),
            0x35..=0x39 => Err(Error::reserved_token()),
            0x3a => Err(Error::unexpected_token()),
            0x3b..=0x3f => Err(Error::reserved_token()),
            token @ 0x40..=0x7f => self.parse_shared_str(token as u16 - 0x40),
            token @ 0x80..=0xbf => self.parse_short_str(token as usize - (0x80 - 1)),
            token @ 0xc0..=0xf7 => self.parse_short_str(token as usize - (0xc0 - 2)),
            0xf8..=0xfa => Err(Error::reserved_token()),
            0xfb => Err(Error::unexpected_token()),
            0xfc..=0xff => Err(Error::reserved_token()),
        }
    }
}

macro_rules! deserialize_integer_key {
    ($method:ident => $visit:ident) => {
        fn $method<V>(mut self, visitor: V) -> Result<V::Value, Error>
        where
            V: Visitor<'de>,
        {
            let s = self.parse_str()?;
            match (s.parse(), s) {
                (Ok(integer), _) => visitor.$visit(integer),
                (Err(_), Str::Short(s)) => visitor.visit_str(s),
                (Err(_), Str::Long(s)) => visitor.visit_borrowed_str(s),
            }
        }
    };
}

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

    fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        match self.parse_str()? {
            Str::Short(s) => visitor.visit_str(s),
            Str::Long(s) => visitor.visit_borrowed_str(s),
        }
    }

    deserialize_integer_key!(deserialize_i8 => visit_i8);
    deserialize_integer_key!(deserialize_i16 => visit_i16);
    deserialize_integer_key!(deserialize_i32 => visit_i32);
    deserialize_integer_key!(deserialize_i64 => visit_i64);

    serde_if_integer128! {
        deserialize_integer_key!(deserialize_i128 => visit_i128);
    }

    deserialize_integer_key!(deserialize_u8 => visit_u8);
    deserialize_integer_key!(deserialize_u16 => visit_u16);
    deserialize_integer_key!(deserialize_u32 => visit_u32);
    deserialize_integer_key!(deserialize_u64 => visit_u64);

    serde_if_integer128! {
        deserialize_integer_key!(deserialize_u128 => visit_u128);
    }

    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        visitor.visit_some(self)
    }

    fn deserialize_newtype_struct<V>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_enum<V>(
        self,
        _name: &'static str,
        _variants: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        visitor.visit_enum(EnumAccess { de: self })
    }

    forward_to_deserialize_any! {
        bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple
        tuple_struct map struct identifier ignored_any
    }

    #[inline]
    fn is_human_readable(&self) -> bool {
        true
    }
}

struct EnumAccess<'a, 'de, R> {
    de: KeyDeserializer<'a, 'de, R>,
}

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

    type Variant = UnitVariantAccess;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        let variant = seed.deserialize(self.de)?;
        Ok((variant, UnitVariantAccess))
    }
}

struct UnitVariantAccess;

impl<'de> de::VariantAccess<'de> for UnitVariantAccess {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Self::Error> {
        Ok(())
    }

    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
    where
        T: de::DeserializeSeed<'de>,
    {
        Err(de::Error::invalid_type(
            de::Unexpected::UnitVariant,
            &"newtype variant",
        ))
    }

    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        Err(de::Error::invalid_type(
            de::Unexpected::UnitVariant,
            &"tuple variant",
        ))
    }

    fn struct_variant<V>(
        self,
        _fields: &'static [&'static str],
        _visitor: V,
    ) -> Result<V::Value, Self::Error>
    where
        V: Visitor<'de>,
    {
        Err(de::Error::invalid_type(
            de::Unexpected::UnitVariant,
            &"struct variant",
        ))
    }
}

enum Str<'a, 'de> {
    Short(&'a str),
    Long(&'de str),
}

impl Deref for Str<'_, '_> {
    type Target = str;

    fn deref(&self) -> &Self::Target {
        match self {
            Str::Short(s) => s,
            Str::Long(s) => s,
        }
    }
}