serde-beve 1.0.0

A BEVE data format for Serde
Documentation
use super::{SeqSerializer, Serializer};
use crate::{Value, error::Error, headers::ObjectKind};
use serde::{
    Serialize,
    ser::{SerializeMap, SerializeStruct, SerializeStructVariant},
};
use std::io::Write;

pub struct MapSerializer<'a, W: Write> {
    serializer: &'a mut Serializer<W>,
    kind: Option<ObjectKind>,
    keys: Vec<Value>,
    values: Vec<Value>,
    key: bool,
}

impl<'a, W: Write> MapSerializer<'a, W> {
    pub fn new(serializer: &'a mut Serializer<W>, kind: Option<ObjectKind>) -> Self {
        serializer.write = false;
        Self {
            serializer,
            kind,
            keys: Vec::new(),
            values: Vec::new(),
            key: false,
        }
    }

    fn ensure_kind(&mut self, expected: ObjectKind) -> Result<(), Error> {
        if self.key {
            match self.kind {
                None => self.kind = Some(expected),
                Some(found) => {
                    if found != expected {
                        return Err(Error::MismatchedKeyType { expected, found });
                    }
                }
            }
        }
        Ok(())
    }
}

impl<'a, W: Write> SerializeMap for MapSerializer<'a, W> {
    type Ok = Value;
    type Error = Error;

    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        self.key = true;
        let key = key.serialize(&mut *self)?;
        self.keys.push(key);
        Ok(())
    }

    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        self.key = false;
        let value = value.serialize(&mut *self)?;
        self.values.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        macro_rules! convert_object {
            ( $( $kind:ident => $object:ident ),* $(,)? ) => {
                match self.kind {
                    None => Value::StringObject(vec![]),
                    $(
                        Some(ObjectKind::$kind) => {
                            let keys = self.keys.into_iter().map(|v| match v {
                                Value::$kind(v) => v,
                                _ => unreachable!(),
                            });
                            let fields = keys.zip(self.values).collect();
                            Value::$object(fields)
                        }
                    )*
                }
            }
        }

        let value = convert_object! {
            String => StringObject,
            I8 => I8Object,
            I16 => I16Object,
            I32 => I32Object,
            I64 => I64Object,
            I128 => I128Object,
            U8 => U8Object,
            U16 => U16Object,
            U32 => U32Object,
            U64 => U64Object,
            U128 => U128Object,
        };

        self.serializer.write = true;
        self.serializer.serialize_value(&value)?;
        Ok(value)
    }
}

impl<'a, W: Write> SerializeStruct for MapSerializer<'a, W> {
    type Ok = Value;
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        self.serialize_key(key)?;
        self.serialize_value(value)?;
        Ok(())
    }

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

impl<'a, W: Write> SerializeStructVariant for MapSerializer<'a, W> {
    type Ok = Value;
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
    where
        T: ?Sized + Serialize,
    {
        self.serialize_key(key)?;
        self.serialize_value(value)?;
        Ok(())
    }

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

macro_rules! serialize_map_type {
    ($fn:ident, $ty:ty, $kind:ident) => {
        fn $fn(self, v: $ty) -> Result<Self::Ok, Self::Error> {
            self.ensure_kind(ObjectKind::$kind)?;
            self.$fn(v)
        }
    };
    ($fn:ident, $ty:ty) => {
        fn $fn(self, v: $ty) -> Result<Self::Ok, Self::Error> {
            if self.key {
                Err(Error::InvalidKey)
            } else {
                self.serializer.$fn(v)
            }
        }
    };
}

impl<'a, 'b, W: Write> serde::Serializer for &'b mut MapSerializer<'a, W> {
    type Ok = Value;
    type Error = Error;

    type SerializeSeq = SeqSerializer<'b, W>;
    type SerializeTuple = SeqSerializer<'b, W>;
    type SerializeTupleStruct = SeqSerializer<'b, W>;
    type SerializeTupleVariant = SeqSerializer<'b, W>;
    type SerializeMap = MapSerializer<'b, W>;
    type SerializeStruct = MapSerializer<'b, W>;
    type SerializeStructVariant = MapSerializer<'b, W>;

    serialize_map_type!(serialize_bool, bool);
    serialize_map_type!(serialize_i8, i8, I8);
    serialize_map_type!(serialize_i16, i16, I16);
    serialize_map_type!(serialize_i32, i32, I32);
    serialize_map_type!(serialize_i64, i64, I64);
    serialize_map_type!(serialize_i128, i128, I128);
    serialize_map_type!(serialize_u8, u8, U8);
    serialize_map_type!(serialize_u16, u16, U16);
    serialize_map_type!(serialize_u32, u32, U32);
    serialize_map_type!(serialize_u64, u64, U64);
    serialize_map_type!(serialize_u128, u128, U128);
    serialize_map_type!(serialize_f32, f32);
    serialize_map_type!(serialize_f64, f64);
    serialize_map_type!(serialize_str, &str, String);
    serialize_map_type!(serialize_bytes, &[u8]);

    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
        self.serialize_str(&v.to_string())
    }

    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
        self.serialize_unit()
    }

    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_unit()
        }
    }

    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
        self.serialize_unit()
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
    ) -> Result<Self::Ok, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer
                .serialize_unit_variant(name, variant_index, variant)
        }
    }

    fn serialize_newtype_struct<T>(
        self,
        name: &'static str,
        value: &T,
    ) -> Result<Self::Ok, Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        self.serializer.serialize_newtype_struct(name, value)
    }

    fn serialize_newtype_variant<T>(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<Self::Ok, Self::Error>
    where
        T: ?Sized + serde::Serialize,
    {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer
                .serialize_newtype_variant(name, variant_index, variant, value)
        }
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_seq(len)
        }
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_tuple(len)
        }
    }

    fn serialize_tuple_struct(
        self,
        name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_tuple_struct(name, len)
        }
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer
                .serialize_tuple_variant(name, variant_index, variant, len)
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_map(len)
        }
    }

    fn serialize_struct(
        self,
        name: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStruct, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer.serialize_struct(name, len)
        }
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Self::Error> {
        if self.key {
            Err(Error::InvalidKey)
        } else {
            self.serializer
                .serialize_struct_variant(name, variant_index, variant, len)
        }
    }
}