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 serde_json::to_value;
use serde_json::Value;

use super::MapKeySerializer;
use super::pair::{Pair, PairBuilder};

pub struct PairSerializer {
    pair: PairBuilder<String, Value>,
    is_key: bool,
}

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

impl Default for PairSerializer {
    fn default() -> Self {
        PairSerializer {
            pair: Pair::new(),
            is_key: true
        }
    }
}

impl ser::Serializer for PairSerializer {
    type Ok = Pair<String, Value>;
    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
        ]
    );

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        match len {
            2 => Ok(self),
            _ => Err(Error::NotAPair),
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        match len {
            Some(1) => Ok(self),
            None => Ok(self),
            _ => Err(Error::NotAPair),
        }
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        match len {
            Some(2) => Ok(self),
            None => Ok(self),
            _ => Err(Error::NotAPair)
        }
    }
}

impl ser::SerializeMap for PairSerializer {
    type Ok = Pair<String, Value>;
    type Error = Error;

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

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: serde::Serialize,
    {
        self.pair.value = Some(to_value(value)?);
        Ok(())
    }

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

impl ser::SerializeSeq for PairSerializer {
    type Ok = Pair<String, Value>;
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: serde::Serialize,
    {
        match self.is_key {
            true => ser::SerializeMap::serialize_key(self, value),
            false => ser::SerializeMap::serialize_value(self, value),
        }
    }

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

impl ser::SerializeTuple for PairSerializer {
    type Ok = Pair<String, Value>;
    type Error = Error;

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

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

#[cfg(test)]
mod tests {
    use serde::Serialize;

    use super::*;
    use std::collections::HashMap;

    #[test]
    fn map() {
        let pair_serializer = PairSerializer::new();

        let map = HashMap::from([("foo", "bar")]);

        let pair = map.serialize(pair_serializer).unwrap();

        assert_eq!(
            Pair {
                key: String::from("foo"),
                value: Value::String(String::from("bar"))
            },
            pair
        );
    }

    #[test]
    fn seq() {
        let pair_serializer = PairSerializer::new();

        let vec = vec!["foo", "bar"];

        let pair = vec.serialize(pair_serializer).unwrap();

        assert_eq!(
            Pair {
                key: String::from("foo"),
                value: Value::String(String::from("bar"))
            },
            pair
        );
    }

    #[test]
    fn tuple() {
        let pair_serializer = PairSerializer::new();

        let tuple = ("foo", "bar");

        let pair = tuple.serialize(pair_serializer).unwrap();

        assert_eq!(
            Pair {
                key: String::from("foo"),
                value: Value::String(String::from("bar"))
            },
            pair
        );
    }
}