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