use serde::{
Serialize, Serializer,
ser::{self, Impossible, SerializeMap, SerializeStruct},
};
pub struct FlatMapSerializer<'a, M>(pub &'a mut M);
fn not_flat<E: ser::Error>() -> E {
E::custom("only a map or a struct has members to write into an open object")
}
macro_rules! refuse {
($($method:ident($($arg:ty),*);)*) => {
$(fn $method(self $(, _: $arg)*) -> Result<Self::Ok, Self::Error> {
Err(not_flat())
})*
};
}
impl<'a, M: SerializeMap> Serializer for FlatMapSerializer<'a, M> {
type Ok = ();
type Error = M::Error;
type SerializeMap = FlatMap<'a, M>;
type SerializeStruct = FlatMap<'a, M>;
type SerializeSeq = Impossible<(), M::Error>;
type SerializeTuple = Impossible<(), M::Error>;
type SerializeTupleStruct = Impossible<(), M::Error>;
type SerializeTupleVariant = Impossible<(), M::Error>;
type SerializeStructVariant = Impossible<(), M::Error>;
refuse! {
serialize_bool(bool);
serialize_i8(i8);
serialize_i16(i16);
serialize_i32(i32);
serialize_i64(i64);
serialize_u8(u8);
serialize_u16(u16);
serialize_u32(u32);
serialize_u64(u64);
serialize_f32(f32);
serialize_f64(f64);
serialize_char(char);
serialize_str(&str);
serialize_bytes(&[u8]);
serialize_none();
serialize_unit();
serialize_unit_struct(&'static str);
serialize_unit_variant(&'static str, u32, &'static str);
}
fn serialize_map(self, _len: Option<usize>) -> Result<FlatMap<'a, M>, M::Error> {
Ok(FlatMap(self.0))
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<FlatMap<'a, M>, M::Error> {
Ok(FlatMap(self.0))
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<(), M::Error> {
value.serialize(self)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_name: &'static str,
value: &T,
) -> Result<(), M::Error> {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_name: &'static str,
_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<(), M::Error> {
Err(not_flat())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, M::Error> {
Err(not_flat())
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, M::Error> {
Err(not_flat())
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, M::Error> {
Err(not_flat())
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, M::Error> {
Err(not_flat())
}
fn serialize_struct_variant(
self,
_name: &'static str,
_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, M::Error> {
Err(not_flat())
}
}
pub struct FlatMap<'a, M>(&'a mut M);
impl<M: SerializeMap> SerializeMap for FlatMap<'_, M> {
type Ok = ();
type Error = M::Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), M::Error> {
self.0.serialize_key(key)
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), M::Error> {
self.0.serialize_value(value)
}
fn end(self) -> Result<(), M::Error> {
Ok(())
}
}
impl<M: SerializeMap> SerializeStruct for FlatMap<'_, M> {
type Ok = ();
type Error = M::Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), M::Error> {
self.0.serialize_entry(key, value)
}
fn skip_field(&mut self, _key: &'static str) -> Result<(), M::Error> {
Ok(())
}
fn end(self) -> Result<(), M::Error> {
Ok(())
}
}