preserves 5.0.0-rc.9

Implementation of the Preserves serialization format.
Documentation
use crate::{Value, Record, Map, IOValue};
use serde::Serialize;

#[derive(Debug)]
pub enum Error {}
impl serde::ser::Error for Error {
    fn custom<T>(_: T) -> Self where T: std::fmt::Display {
        unreachable!()
    }
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
    fn fmt(&self, _fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
        unreachable!()
    }
}

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

pub struct Serializer;

pub struct SerializeDictionary {
    next_key: Option<IOValue>,
    items: Map<IOValue, IOValue>,
}

pub struct SerializeRecord {
    label_and_fields: Vec<Value<IOValue>>,
}

pub struct SerializeSequence {
    vec: Vec<IOValue>,
}

impl serde::Serializer for Serializer {
    type Ok = IOValue;
    type Error = Error;
    type SerializeSeq = SerializeSequence;
    type SerializeTuple = SerializeRecord;
    type SerializeTupleStruct = SerializeRecord;
    type SerializeTupleVariant = SerializeRecord;
    type SerializeMap = SerializeDictionary;
    type SerializeStruct = SerializeRecord;
    type SerializeStructVariant = SerializeRecord;

    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
        Ok(IOValue::new(v as f64))
    }

    fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
        Ok(IOValue::new(v))
    }

    fn serialize_char(self, v: char) -> Result<Self::Ok> {
        Ok(IOValue::record(IOValue::symbol("UnicodeScalar"), vec![IOValue::new(v as u32)]))
    }

    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
        Ok(IOValue::new(v.to_owned()))
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
        Ok(IOValue::bytes(v.to_vec()))
    }

    fn serialize_none(self) -> Result<Self::Ok> {
        Ok(IOValue::record(IOValue::symbol("None"), vec![]))
    }

    fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
        Ok(IOValue::record(IOValue::symbol("Some"), vec![to_value(v).into()]))
    }

    fn serialize_unit(self) -> Result<Self::Ok> {
        Ok(IOValue::record(IOValue::symbol("tuple"), vec![]))
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
        Ok(IOValue::record(IOValue::symbol(name), vec![]))
    }

    fn serialize_unit_variant(self,
                              _name: &'static str,
                              _variant: u32,
                              variant_name: &'static str) ->
        Result<Self::Ok>
    {
        Ok(IOValue::record(IOValue::symbol(variant_name), vec![]))
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
        Result<Self::Ok> where T: Serialize
    {
        match super::magic::receive_output_value(name, value) {
            Some(v) => Ok(v),
            None => {
                // TODO: This is apparently discouraged, and we should apparently just serialize `value`?
                Ok(IOValue::record(IOValue::symbol(name), vec![to_value(value).into()]))
            }
        }
    }

    fn serialize_newtype_variant<T: ?Sized>(self,
                                            _name: &'static str,
                                            _variant: u32,
                                            variant_name: &'static str,
                                            value: &T) ->
        Result<Self::Ok> where T: Serialize
    {
        Ok(IOValue::record(IOValue::symbol(variant_name), vec![to_value(value).into()]))
    }

    fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
        let vec = match count { Some(n) => Vec::with_capacity(n), None => Vec::new() };
        Ok(SerializeSequence { vec })
    }

    fn serialize_tuple(self, _count: usize) -> Result<Self::SerializeTuple> {
        Ok(SerializeRecord::new("tuple"))
    }

    fn serialize_tuple_struct(self, name: &'static str, _count: usize) ->
        Result<Self::SerializeTupleStruct>
    {
        Ok(SerializeRecord::new(name))
    }

    fn serialize_tuple_variant(self,
                               _name: &'static str,
                               _variant: u32,
                               variant_name: &'static str,
                               _count: usize) ->
        Result<Self::SerializeTupleVariant>
    {
        Ok(SerializeRecord::new(variant_name))
    }

    fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
        Ok(SerializeDictionary { next_key: None, items: Map::new() })
    }

    fn serialize_struct(self, name: &'static str, _count: usize) -> Result<Self::SerializeStruct> {
        Ok(SerializeRecord::new(name))
    }

    fn serialize_struct_variant(self,
                                _name: &'static str,
                                _variant: u32,
                                variant_name: &'static str,
                                _count: usize) ->
        Result<Self::SerializeStructVariant>
    {
        Ok(SerializeRecord::new(variant_name))
    }
}

impl serde::ser::SerializeMap for SerializeDictionary {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
        self.next_key = Some(to_value(key));
        Ok(())
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        let key = self.next_key.take().unwrap();
        self.items.insert(key, to_value(value));
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(IOValue::new(self.items))
    }
}

impl SerializeRecord {
    fn new(label: &str) -> Self {
        SerializeRecord { label_and_fields: vec![Value::symbol(label.to_owned())] }
    }

    fn push<T: ?Sized>(&mut self, value: &T)
    where T: Serialize
    {
        self.label_and_fields.push(to_value(value).into())
    }

    fn finish(self) -> IOValue {
        IOValue::new(Record::_from_vec(self.label_and_fields))
    }
}

impl serde::ser::SerializeStruct for SerializeRecord {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
    where T: Serialize
    {
        self.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(self.finish())
    }
}

impl serde::ser::SerializeStructVariant for SerializeRecord {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
    where T: Serialize
    {
        self.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(self.finish())
    }
}

impl serde::ser::SerializeTuple for SerializeRecord {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        self.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(self.finish())
    }
}

impl serde::ser::SerializeTupleStruct for SerializeRecord {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        self.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(self.finish())
    }
}

impl serde::ser::SerializeTupleVariant for SerializeRecord {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        self.push(value);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(self.finish())
    }
}

impl serde::ser::SerializeSeq for SerializeSequence {
    type Ok = IOValue;
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
        self.vec.push(to_value(value));
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        Ok(IOValue::new(self.vec))
    }
}

pub fn to_value<T>(value: T) -> IOValue where T: Serialize {
    value.serialize(Serializer).unwrap()
}