From ff4c6821bf2be67aaecd574181b430e34092442b Mon Sep 17 00:00:00 2001 From: Sam Rijs Date: Tue, 11 Sep 2018 20:54:59 +1000 Subject: [PATCH] Refactor to make "special" type machinery more reusable --- src/ser.rs | 20 +++--------- src/value/de.rs | 84 +++++++++++++++++++----------------------------- src/value/ser.rs | 23 +++---------- 3 files changed, 43 insertions(+), 84 deletions(-) diff --git a/src/ser.rs b/src/ser.rs index 4214d0ce6..ca9b637ee 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -22,9 +22,6 @@ use ryu; #[cfg(feature = "arbitrary_precision")] use serde::Serialize; -#[cfg(feature = "arbitrary_precision")] -use number::{SERDE_STRUCT_FIELD_NAME, SERDE_STRUCT_NAME}; - /// A structure for serializing Rust values into JSON. pub struct Serializer { writer: W, @@ -461,19 +458,12 @@ where } } - #[cfg(not(feature = "arbitrary_precision"))] - #[inline] - fn serialize_struct(self, _name: &'static str, len: usize) -> Result { - self.serialize_map(Some(len)) - } - - #[cfg(feature = "arbitrary_precision")] #[inline] fn serialize_struct(self, name: &'static str, len: usize) -> Result { - if name == SERDE_STRUCT_NAME { - Ok(Compound::Number { ser: self }) - } else { - self.serialize_map(Some(len)) + match name { + #[cfg(feature = "arbitrary_precision")] + ::number::SERDE_STRUCT_NAME => Ok(Compound::Number { ser: self }), + _ => self.serialize_map(Some(len)), } } @@ -820,7 +810,7 @@ where } #[cfg(feature = "arbitrary_precision")] Compound::Number { ref mut ser, .. } => { - if key == SERDE_STRUCT_FIELD_NAME { + if key == ::number::SERDE_STRUCT_FIELD_NAME { try!(value.serialize(NumberStrEmitter(&mut *ser))); Ok(()) } else { diff --git a/src/value/de.rs b/src/value/de.rs index 67b18bebb..dc8dbc6be 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -23,11 +23,10 @@ use map::Map; use number::Number; use value::Value; -#[cfg(feature = "arbitrary_precision")] use serde::de; #[cfg(feature = "arbitrary_precision")] -use number::{NumberFromString, SERDE_STRUCT_FIELD_NAME}; +use number::NumberFromString; impl<'de> Deserialize<'de> for Value { #[inline] @@ -109,44 +108,28 @@ impl<'de> Deserialize<'de> for Value { Ok(Value::Array(vec)) } - #[cfg(not(feature = "arbitrary_precision"))] - fn visit_map(self, mut visitor: V) -> Result - where - V: MapAccess<'de>, - { - let mut values = Map::new(); - - while let Some((key, value)) = try!(visitor.next_entry()) { - values.insert(key, value); - } - - Ok(Value::Object(values)) - } - - #[cfg(feature = "arbitrary_precision")] fn visit_map(self, mut visitor: V) -> Result where V: MapAccess<'de>, { - let mut key = String::new(); - let number = visitor.next_key_seed(NumberOrObject { key: &mut key })?; - match number { - Some(true) => { + match visitor.next_key_seed(KeyClassifier)? { + #[cfg(feature = "arbitrary_precision")] + Some(KeyClass::Number) => { let number: NumberFromString = visitor.next_value()?; return Ok(Value::Number(number.value)); } - None => return Ok(Value::Object(Map::new())), - Some(false) => {} - } + Some(KeyClass::Map(first_key)) => { + let mut values = Map::new(); - let mut values = Map::new(); + values.insert(first_key, try!(visitor.next_value())); + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } - values.insert(key, try!(visitor.next_value())); - while let Some((key, value)) = try!(visitor.next_entry()) { - values.insert(key, value); + Ok(Value::Object(values)) + } + None => return Ok(Value::Object(Map::new())), } - - Ok(Value::Object(values)) } } @@ -1303,14 +1286,16 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { } } -#[cfg(feature = "arbitrary_precision")] -struct NumberOrObject<'a> { - key: &'a mut String, +struct KeyClassifier; + +enum KeyClass { + Map(String), + #[cfg(feature = "arbitrary_precision")] + Number, } -#[cfg(feature = "arbitrary_precision")] -impl<'a, 'de> DeserializeSeed<'de> for NumberOrObject<'a> { - type Value = bool; +impl<'de> DeserializeSeed<'de> for KeyClassifier { + type Value = KeyClass; fn deserialize(self, deserializer: D) -> Result where @@ -1320,35 +1305,32 @@ impl<'a, 'de> DeserializeSeed<'de> for NumberOrObject<'a> { } } -#[cfg(feature = "arbitrary_precision")] -impl<'a, 'de> Visitor<'de> for NumberOrObject<'a> { - type Value = bool; +impl<'de> Visitor<'de> for KeyClassifier { + type Value = KeyClass; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a string key") } - fn visit_str(self, s: &str) -> Result + fn visit_str(self, s: &str) -> Result where E: de::Error, { - if s == SERDE_STRUCT_FIELD_NAME { - Ok(true) - } else { - self.key.push_str(s); - Ok(false) + match s { + #[cfg(feature = "arbitrary_precision")] + ::number::SERDE_STRUCT_FIELD_NAME => Ok(KeyClass::Number), + _ => Ok(KeyClass::Map(s.to_owned())), } } - fn visit_string(self, s: String) -> Result + fn visit_string(self, s: String) -> Result where E: de::Error, { - if s == SERDE_STRUCT_FIELD_NAME { - Ok(true) - } else { - *self.key = s; - Ok(false) + match s.as_str() { + #[cfg(feature = "arbitrary_precision")] + ::number::SERDE_STRUCT_FIELD_NAME => Ok(KeyClass::Number), + _ => Ok(KeyClass::Map(s)), } } } diff --git a/src/value/ser.rs b/src/value/ser.rs index 26595cc47..d3f71b373 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -17,9 +17,6 @@ use value::{to_value, Value}; #[cfg(feature = "arbitrary_precision")] use serde::ser; -#[cfg(feature = "arbitrary_precision")] -use number::{SERDE_STRUCT_FIELD_NAME, SERDE_STRUCT_NAME}; - impl Serialize for Value { #[inline] fn serialize(&self, serializer: S) -> Result @@ -228,25 +225,15 @@ impl serde::Serializer for Serializer { }) } - #[cfg(not(feature = "arbitrary_precision"))] - fn serialize_struct( - self, - _name: &'static str, - len: usize, - ) -> Result { - self.serialize_map(Some(len)) - } - - #[cfg(feature = "arbitrary_precision")] fn serialize_struct( self, name: &'static str, len: usize, ) -> Result { - if name == SERDE_STRUCT_NAME { - Ok(SerializeMap::Number { out_value: None }) - } else { - self.serialize_map(Some(len)) + match name { + #[cfg(feature = "arbitrary_precision")] + ::number::SERDE_STRUCT_NAME => Ok(SerializeMap::Number { out_value: None }), + _ => self.serialize_map(Some(len)), } } @@ -605,7 +592,7 @@ impl serde::ser::SerializeStruct for SerializeMap { } #[cfg(feature = "arbitrary_precision")] SerializeMap::Number { ref mut out_value } => { - if key == SERDE_STRUCT_FIELD_NAME { + if key == ::number::SERDE_STRUCT_FIELD_NAME { *out_value = Some(value.serialize(NumberValueEmitter)?); Ok(()) } else {