Created
November 1, 2017 13:40
-
-
Save Marwes/c09c42899d01362d682daa67fecd34a7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use serde::{Deserialize, Deserializer, Serialize, Serializer}; | |
pub struct Readable<T: ?Sized>(T); | |
pub struct Compact<T: ?Sized>(T); | |
pub trait Configure { | |
fn readable(&self) -> Readable<&Self> { | |
Readable(self) | |
} | |
fn compact(&self) -> Compact<&Self> { | |
Compact(self) | |
} | |
} | |
impl<T: ?Sized> Configure for T {} | |
impl<T: ?Sized> Serialize for Readable<T> | |
where | |
T: Serialize, | |
{ | |
#[inline] | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: Serializer, | |
{ | |
self.0.serialize(Readable(serializer)) | |
} | |
} | |
impl<T: ?Sized> Serialize for Compact<T> | |
where | |
T: Serialize, | |
{ | |
#[inline] | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: Serializer, | |
{ | |
self.0.serialize(Compact(serializer)) | |
} | |
} | |
impl<'de, T> Deserialize<'de> for Readable<T> | |
where | |
T: Deserialize<'de>, | |
{ | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: Deserializer<'de>, | |
{ | |
T::deserialize(Readable(deserializer)).map(Readable) | |
} | |
} | |
impl<'de, T> Deserialize<'de> for Compact<T> | |
where | |
T: Deserialize<'de>, | |
{ | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
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<(), Error>); | |
)* | |
}; | |
} | |
impl<S> Serializer for Readable<S> | |
where | |
S: Serializer, | |
{ | |
type Ok = S::Ok; | |
type Error = S::Error; | |
type SerializeSeq = S::SerializeSeq; | |
type SerializeTuple = S::SerializeTuple; | |
type SerializeTupleStruct = S::SerializeTupleStruct; | |
type SerializeTupleVariant = S::SerializeTupleVariant; | |
type SerializeMap = S::SerializeMap; | |
type SerializeStruct = S::SerializeStruct; | |
type SerializeStructVariant = S::SerializeStructVariant; | |
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<(), Error> { | |
self.0.serialize_unit() | |
} | |
fn serialize_unit_variant( | |
self, | |
name: &'static str, | |
_variant_index: u32, | |
variant: &'static str, | |
) -> Result<(), Error> { | |
if self.tokens.first() == Some(&Token::Enum { name: name }) { | |
self.next_token(); | |
assert_next_token!(self, Str(variant)); | |
assert_next_token!(self, Unit); | |
} else { | |
assert_next_token!(self, UnitVariant { name, variant }); | |
} | |
Ok(()) | |
} | |
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error> | |
where | |
T: Serialize, | |
{ | |
assert_next_token!(self, NewtypeStruct { name }); | |
value.serialize(self) | |
} | |
fn serialize_newtype_variant<T: ?Sized>( | |
self, | |
name: &'static str, | |
_variant_index: u32, | |
variant: &'static str, | |
value: &T, | |
) -> Result<(), Error> | |
where | |
T: Serialize, | |
{ | |
if self.tokens.first() == Some(&Token::Enum { name: name }) { | |
self.next_token(); | |
assert_next_token!(self, Str(variant)); | |
} else { | |
assert_next_token!(self, NewtypeVariant { name, variant }); | |
} | |
value.serialize(self) | |
} | |
fn serialize_none(self) -> Result<(), Error> { | |
assert_next_token!(self, None); | |
Ok(()) | |
} | |
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error> | |
where | |
T: Serialize, | |
{ | |
assert_next_token!(self, Some); | |
value.serialize(self) | |
} | |
fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> { | |
assert_next_token!(self, Seq { len }); | |
Ok(self) | |
} | |
fn serialize_tuple(self, len: usize) -> Result<Self, Error> { | |
assert_next_token!(self, Tuple { len }); | |
Ok(self) | |
} | |
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> { | |
assert_next_token!(self, TupleStruct { name, len }); | |
Ok(self) | |
} | |
fn serialize_tuple_variant( | |
self, | |
name: &'static str, | |
_variant_index: u32, | |
variant: &'static str, | |
len: usize, | |
) -> Result<Self::SerializeTupleVariant, Error> { | |
if self.tokens.first() == Some(&Token::Enum { name: name }) { | |
self.next_token(); | |
assert_next_token!(self, Str(variant)); | |
let len = Some(len); | |
assert_next_token!(self, Seq { len }); | |
Ok(Variant { | |
ser: self, | |
end: Token::SeqEnd, | |
}) | |
} else { | |
assert_next_token!(self, TupleVariant { name, variant, len }); | |
Ok(Variant { | |
ser: self, | |
end: Token::TupleVariantEnd, | |
}) | |
} | |
} | |
fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> { | |
assert_next_token!(self, Map { len }); | |
Ok(self) | |
} | |
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> { | |
assert_next_token!(self, Struct { name, len }); | |
Ok(self) | |
} | |
fn serialize_struct_variant( | |
self, | |
name: &'static str, | |
_variant_index: u32, | |
variant: &'static str, | |
len: usize, | |
) -> Result<Self::SerializeStructVariant, Error> { | |
if self.tokens.first() == Some(&Token::Enum { name: name }) { | |
self.next_token(); | |
assert_next_token!(self, Str(variant)); | |
let len = Some(len); | |
assert_next_token!(self, Map { len }); | |
Ok(Variant { | |
ser: self, | |
end: Token::MapEnd, | |
}) | |
} else { | |
assert_next_token!(self, StructVariant { name, variant, len }); | |
Ok(Variant { | |
ser: self, | |
end: Token::StructVariantEnd, | |
}) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment