From 78fab25c5cec133c254ec1997aa11597d59f0b09 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 2 Nov 2017 14:52:25 +0100 Subject: [PATCH] implement Serializer for Readable/Compact --- serde_test/src/configure.rs | 374 ++++++++++++++++++++++++++++++++++++ serde_test/src/lib.rs | 1 + 2 files changed, 375 insertions(+) create mode 100644 serde_test/src/configure.rs diff --git a/serde_test/src/configure.rs b/serde_test/src/configure.rs new file mode 100644 index 00000000..fa4233bb --- /dev/null +++ b/serde_test/src/configure.rs @@ -0,0 +1,374 @@ +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, + SerializeTuple, SerializeTupleStruct, SerializeTupleVariant}; + +pub struct Readable(T); +pub struct Compact(T); + +pub trait Configure { + fn readable(&self) -> Readable<&Self> { + Readable(self) + } + fn compact(&self) -> Compact<&Self> { + Compact(self) + } +} + +impl Configure for T {} +pub trait Configuration { + fn is_human_readable(&self) -> bool { + true + } +} +impl Configuration for Readable {} + +fn assert(_: T) +where + T: Configure, +{ + +} + +impl Serialize for Readable +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(Readable(serializer)) + } +} +impl Serialize for Compact +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(Compact(serializer)) + } +} +impl<'de, T> Deserialize<'de> for Readable +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(Readable(deserializer)).map(Readable) + } +} +impl<'de, T> Deserialize<'de> for Compact +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(Compact(deserializer)).map(Compact) + } +} + + +macro_rules! forward_method { + ($name: ident (self $(, $arg: ident : $arg_type: ty)* ) -> $return_type: ty) => { + fn $name (self $(, $arg : $arg_type)* ) -> $return_type { + (self.0).$name( $($arg),* ) + } + }; +} + +macro_rules! forward_serialize_methods { + ( $( $name: ident $arg_type: ty ),* ) => { + $( + forward_method!($name(self, v : $arg_type) -> Result); + )* + }; +} + +macro_rules! impl_serializer { + ($wrapper: ident, $is_human_readable : expr) => { + impl Serializer for $wrapper + where + S: Serializer, + { + type Ok = S::Ok; + type Error = S::Error; + + type SerializeSeq = $wrapper; + type SerializeTuple = $wrapper; + type SerializeTupleStruct = $wrapper; + type SerializeTupleVariant = $wrapper; + type SerializeMap = $wrapper; + type SerializeStruct = $wrapper; + type SerializeStructVariant = $wrapper; + + fn is_human_readable(&self) -> bool { + $is_human_readable + } + + + forward_serialize_methods!{ + 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_unit_struct &'static str + + } + + fn serialize_unit(self) -> Result { + self.0.serialize_unit() + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + self.0.serialize_unit_variant(name, variant_index, variant) + } + + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + self.0.serialize_newtype_struct(name, &$wrapper(value)) + } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + self.0 + .serialize_newtype_variant(name, variant_index, variant, &$wrapper(value)) + } + + fn serialize_none(self) -> Result { + self.0.serialize_none() + } + + fn serialize_some(self, value: &T) -> Result + where + T: Serialize, + { + self.0.serialize_some(&$wrapper(value)) + } + + fn serialize_seq(self, len: Option) -> Result { + self.0.serialize_seq(len).map($wrapper) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.0.serialize_tuple(len).map($wrapper) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + self.0.serialize_tuple_struct(name, len).map($wrapper) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + self.0 + .serialize_tuple_variant(name, variant_index, variant, len) + .map($wrapper) + } + + fn serialize_map(self, len: Option) -> Result { + self.0.serialize_map(len).map($wrapper) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + self.0.serialize_struct(name, len).map($wrapper) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + self.0 + .serialize_struct_variant(name, variant_index, variant, len) + .map($wrapper) + } + } + + impl SerializeSeq for $wrapper + where + S: SerializeSeq, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_element(&mut self, value: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_element(&$wrapper(value)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeTuple for $wrapper + where + S: SerializeTuple, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_element(&mut self, value: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_element(&$wrapper(value)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeTupleStruct for $wrapper + where + S: SerializeTupleStruct, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_field(&mut self, value: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_field(&$wrapper(value)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeTupleVariant for $wrapper + where + S: SerializeTupleVariant, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_field(&mut self, value: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_field(&$wrapper(value)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeMap for $wrapper + where + S: SerializeMap, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_key(&mut self, key: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_key(&$wrapper(key)) + } + fn serialize_value(&mut self, value: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_value(&$wrapper(value)) + } + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), S::Error> + where + K: Serialize, + V: Serialize, + { + self.0.serialize_entry(key, &$wrapper(value)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeStruct for $wrapper + where + S: SerializeStruct, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_field(&mut self, name: &'static str, field: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_field(name, &$wrapper(field)) + } + fn end(self) -> Result { + self.0.end() + } + } + + impl SerializeStructVariant for $wrapper + where + S: SerializeStructVariant, + { + type Ok = S::Ok; + type Error = S::Error; + fn serialize_field(&mut self, name: &'static str, field: &T) -> Result<(), S::Error> + where + T: Serialize, + { + self.0.serialize_field(name, &$wrapper(field)) + } + fn end(self) -> Result { + self.0.end() + } + } + } +} + +impl_serializer!(Readable, true); +impl_serializer!(Compact, false); diff --git a/serde_test/src/lib.rs b/serde_test/src/lib.rs index 4068e58b..79b1a96a 100644 --- a/serde_test/src/lib.rs +++ b/serde_test/src/lib.rs @@ -164,6 +164,7 @@ mod ser; mod de; mod error; +mod configure; mod token; mod assert;