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
);
}
}