json_map_serializer 0.1.3

Crate for easy serializing json maps from sequense of pairs
Documentation
use crate::Error;
use impl_serialize::impl_serialize;
use serde::ser;
use crate::JsonMap;

mod map_key_serializer;
use map_key_serializer::MapKeySerializer;

mod pair_serializer;
mod pair;
use pair_serializer::PairSerializer;

#[derive(Default)]
pub struct MapSerializer {
    map: JsonMap,
    next_key: Option<String>
}

impl MapSerializer {
    pub fn new() -> MapSerializer {
        MapSerializer::default()
    }
}

impl ser::Serializer for MapSerializer {
    type Ok = JsonMap;
    type Error = Error;

    type SerializeMap = Self;
    type SerializeSeq = Self;
    type SerializeTuple = Self;

    type SerializeStruct = ser::Impossible<Self::Ok, Self::Error>;
    type SerializeStructVariant = ser::Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = ser::Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = ser::Impossible<Self::Ok, Self::Error>;

    impl_serialize!(
        Err(Error::CannotSerializeAsObject(value_type.to_string())),
        [
            bool,
            bytes,
            i8, i16, i32, i64,
            u8, u16, u32, u64,
            f32, f64,
            char,
            str,
            none, some, unit,
            unit_struct, unit_variant,
            newtype_struct, newtype_variant,
            tuple_struct, tuple_variant,
            struct, struct_variant
        ]
    );

    impl_serialize!(
        Ok(self),
        [
            seq, map, tuple
        ]
    );
}

impl ser::SerializeMap for MapSerializer {
    type Ok = JsonMap;
    type Error = Error;

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

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: serde::Serialize,
    {
        let key = self.next_key.take();
        
        // Panic because this indicates a bug in the program rather than an
        // expected failure.
        let key = key.expect("serialize_value called before serialize_key");
        self.map.insert(key, serde_json::to_value(&value)?);
        Ok(())
    }

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

impl ser::SerializeSeq for MapSerializer {
    type Ok = JsonMap;
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: serde::Serialize
    {
        ser::SerializeTuple::serialize_element(self, value)
    }

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

impl ser::SerializeTuple for MapSerializer {
    type Ok = JsonMap;
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: serde::Serialize
    {
        let pair = value.serialize(PairSerializer::new())?;
        self.map.insert(pair.key, pair.value);

        Ok(())
    }

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

#[cfg(test)]
mod tests {
    use serde::Serialize;
    use serde_json::Value;
    
    use super::*;
    use std::collections::HashMap;

    #[test]
    fn map() {
        let map_serializer = MapSerializer::new();
        let hash_map = HashMap::from([("foo", "bar"), ("baz", "qux")]);
        let map = hash_map.serialize(map_serializer).unwrap();

        let mut correct_result = JsonMap::new();
        correct_result.insert(String::from("foo"), Value::String(String::from("bar")));
        correct_result.insert(String::from("baz"), Value::String(String::from("qux")));

        assert_eq!(map, correct_result);
    }

    #[test]
    fn seq() {
        let map_serializer = MapSerializer::new();
        let seq = vec![("foo", "bar"), ("baz", "qux")];
        let map = seq.serialize(map_serializer).unwrap();

        let mut correct_result = JsonMap::new();
        correct_result.insert(String::from("foo"), Value::String(String::from("bar")));
        correct_result.insert(String::from("baz"), Value::String(String::from("qux")));

        assert_eq!(map, correct_result);
    }

    #[test]
    fn tuple() {
        let map_serializer = MapSerializer::new();
        let tuple = (("foo", "bar"), ("baz", "qux"));
        let map = tuple.serialize(map_serializer).unwrap();

        let mut correct_result = JsonMap::new();
        correct_result.insert(String::from("foo"), Value::String(String::from("bar")));
        correct_result.insert(String::from("baz"), Value::String(String::from("qux")));

        assert_eq!(map, correct_result);
    }

    #[test]
    fn not_a_pair() {
        let map_serializer = MapSerializer::new();
        let tuple = (("foo", "qux", "baz"), ("bar"));
        
        assert_eq!(
            tuple.serialize(map_serializer).err().unwrap(),
            Error::NotAPair
        );
    }
}