serde_ron 1.0.0

Serde (De)Serializer for Rust Object Notation
Documentation
use serde::de::{Visitor, SeqAccess, MapAccess, DeserializeSeed, Unexpected, Error as _, VariantAccess, EnumAccess};
use serde::{forward_to_deserialize_any};

use std::collections::BTreeMap;

use crate::value::{Primitive, Value, Number, Data};
use crate::Error;

type Result<V> = std::result::Result<V, Error>;

impl<'de> serde::Deserializer<'de> for Value {
    type Error = Error;

    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
        match self {
            Value::Primitive(field) => match field {
                Primitive::Unit => visitor.visit_unit(),
                Primitive::bool(b) => visitor.visit_bool(b),
                Primitive::Number(number) => match number {
                    Number::i8(i) => visitor.visit_i8(i),
                    Number::i16(i) => visitor.visit_i16(i),
                    Number::i32(i) => visitor.visit_i32(i),
                    Number::i64(i) => visitor.visit_i64(i),
                    Number::i128(i) => visitor.visit_i128(i),
                    Number::u8(i) => visitor.visit_u8(i),
                    Number::u16(i) => visitor.visit_u16(i),
                    Number::u32(i) => visitor.visit_u32(i),
                    Number::u64(i) => visitor.visit_u64(i),
                    Number::u128(i) => visitor.visit_u128(i),
                    Number::f32(i) => visitor.visit_f32(i),
                    Number::f64(i) => visitor.visit_f64(i),
                }
                Primitive::char(c) => visitor.visit_char(c),
                Primitive::String(s) => visitor.visit_string(s),
                Primitive::Bytes(b) => visitor.visit_byte_buf(b)
            },
            Value::Variant(_name, variant, data) => visitor.visit_enum(Variant(variant, data)),
            Value::Struct(_name, data) => match data {
                Data::Unit => visitor.visit_map(Struct(BTreeMap::new(), None)),
                Data::Tuple(objects) => visitor.visit_seq(Seq::new(objects)),
                Data::NewType(i) => visitor.visit_newtype_struct(*i),
                Data::Struct(fields) => visitor.visit_map(Struct(fields, None))
            },
            Value::Tuple(objects) => visitor.visit_seq(Seq::new(objects)),
            Value::Vec(objects) => visitor.visit_seq(Seq::new(objects)),
            Value::Map(objects) => visitor.visit_map(Map(objects, None)),
            Value::Some(b) => visitor.visit_some(*b),
            Value::None => visitor.visit_none(),
        }
    }

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

    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 identifier ignored_any
    }
}

pub struct Map(BTreeMap<Value, Value>, Option<Value>);
impl<'de> MapAccess<'de> for Map {
    type Error = Error;

    fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
        self.0.pop_first().map(|(k, v)| {self.1 = Some(v); seed.deserialize(k)}).transpose()
    }

    fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
        seed.deserialize(self.1.take().unwrap())
    }
}

pub struct Struct(BTreeMap<String, Value>, Option<Value>);
impl<'de> MapAccess<'de> for Struct {
    type Error = Error;

    fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
        self.0.pop_first().map(|(k, v)| {self.1 = Some(v); seed.deserialize(Value::Primitive(Primitive::String(k)))}).transpose()
    }

    fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
        seed.deserialize(self.1.take().unwrap())
    }
}

pub struct Seq(Vec<Value>);
impl Seq {
    pub fn new(objects: Vec<Value>) -> Self {Seq(objects.into_iter().rev().collect())}
}
impl<'de> SeqAccess<'de> for Seq {
    type Error = Error;

    fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
        self.0.pop().map(|o| seed.deserialize(o)).transpose()
    }
}

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

    fn unit_variant(self) -> Result<()> {
        match self {
            Data::Unit => Ok(()),
            Data::NewType(_) => Err(Error::invalid_type(Unexpected::NewtypeVariant, &"unit variant")),
            Data::Tuple(_) => Err(Error::invalid_type(Unexpected::TupleVariant, &"unit variant")),
            Data::Struct(_) => Err(Error::invalid_type(Unexpected::StructVariant, &"unit variant"))
        }
    }

    fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
        match self {
            Data::Unit => Err(Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")),
            Data::NewType(i) => seed.deserialize(*i),
            Data::Tuple(_) => Err(Error::invalid_type(Unexpected::TupleVariant, &"newtype variant")),
            Data::Struct(_) => Err(Error::invalid_type(Unexpected::StructVariant, &"newtype variant"))
        }
    }

    fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
        match self {
            Data::Unit => Err(Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")),
            Data::NewType(_) => Err(Error::invalid_type(Unexpected::NewtypeVariant, &"tuple variant")),
            Data::Tuple(objects) => visitor.visit_seq(Seq::new(objects)),
            Data::Struct(_) => Err(Error::invalid_type(Unexpected::StructVariant, &"tuple variant"))
        }
    }

    fn struct_variant<V: Visitor<'de>>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value> {
        match self {
            Data::Unit => Err(Error::invalid_type(Unexpected::UnitVariant, &"struct variant")),
            Data::NewType(_) => Err(Error::invalid_type(Unexpected::NewtypeVariant, &"struct variant")),
            Data::Tuple(_) => Err(Error::invalid_type(Unexpected::TupleVariant, &"struct variant")),
            Data::Struct(fields) => visitor.visit_map(Struct(fields, None))
        }
    }
}

pub struct Variant(String, Data);
impl<'de> EnumAccess<'de> for Variant {
    type Error = Error;
    type Variant = Data;

    fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Data)> {
        seed.deserialize(Value::Primitive(Primitive::String(self.0))).map(|v| (v, self.1))
    }
}