From 6277079152bb933b8ea2a3d6f3d1af5720dac31b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 3 Feb 2017 15:02:40 +0100 Subject: [PATCH] move the PhantomData usage to the Deserializer --- serde/src/de/content.rs | 180 +++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 87 deletions(-) diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs index 292d6a442..5876f6157 100644 --- a/serde/src/de/content.rs +++ b/serde/src/de/content.rs @@ -18,15 +18,17 @@ use de::{ EnumVisitor, }; +use de::value::ValueDeserializer; + /// Used from generated code to buffer the contents of the Deserializer when /// deserializing untagged enums and internally tagged enums. /// /// Not public API. Use serde-value instead. #[allow(missing_docs)] #[derive(Debug)] -pub enum Content { +pub enum Content { // Don't mind the PhantomData, just need to use E somewhere. - Bool(bool, PhantomData), + Bool(bool), U8(u8), U16(u16), @@ -46,36 +48,26 @@ pub enum Content { Bytes(Vec), None, - Some(Box>), + Some(Box), Unit, - Newtype(Box>), - Seq(Vec>), - Map(Vec<(Content, Content)>), + Newtype(Box), + Seq(Vec), + Map(Vec<(Content, Content)>), } -impl Deserialize for Content { +impl Deserialize for Content { fn deserialize(deserializer: D) -> Result { // Untagged and internally tagged enums are only supported in // self-describing formats. - deserializer.deserialize(ContentVisitor::new()) + deserializer.deserialize(ContentVisitor) } } -struct ContentVisitor { - err: PhantomData, -} - -impl ContentVisitor { - fn new() -> Self { - ContentVisitor { - err: PhantomData, - } - } -} +struct ContentVisitor; -impl Visitor for ContentVisitor { - type Value = Content; +impl Visitor for ContentVisitor { + type Value = Content; fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.write_str("any value") @@ -84,7 +76,7 @@ impl Visitor for ContentVisitor { fn visit_bool(self, value: bool) -> Result where F: de::Error { - Ok(Content::Bool(value, PhantomData)) + Ok(Content::Bool(value)) } fn visit_i8(self, value: i8) -> Result @@ -231,27 +223,25 @@ impl Visitor for ContentVisitor { /// This is the type of the map keys in an internally tagged enum. /// /// Not public API. -pub enum TagOrContent { +pub enum TagOrContent { Tag, - Content(Content), + Content(Content), } -struct TagOrContentVisitor { +struct TagOrContentVisitor { name: &'static str, - err: PhantomData, } -impl TagOrContentVisitor { +impl TagOrContentVisitor { fn new(name: &'static str) -> Self { TagOrContentVisitor { name: name, - err: PhantomData, } } } -impl DeserializeSeed for TagOrContentVisitor { - type Value = TagOrContent; +impl DeserializeSeed for TagOrContentVisitor { + type Value = TagOrContent; fn deserialize(self, deserializer: D) -> Result where D: Deserializer @@ -262,8 +252,8 @@ impl DeserializeSeed for TagOrContentVisitor { } } -impl Visitor for TagOrContentVisitor { - type Value = TagOrContent; +impl Visitor for TagOrContentVisitor { + type Value = TagOrContent; fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "a type tag `{}` or any other value", self.name) @@ -272,73 +262,73 @@ impl Visitor for TagOrContentVisitor { fn visit_bool(self, value: bool) -> Result where F: de::Error { - ContentVisitor::new().visit_bool(value).map(TagOrContent::Content) + ContentVisitor.visit_bool(value).map(TagOrContent::Content) } fn visit_i8(self, value: i8) -> Result where F: de::Error { - ContentVisitor::new().visit_i8(value).map(TagOrContent::Content) + ContentVisitor.visit_i8(value).map(TagOrContent::Content) } fn visit_i16(self, value: i16) -> Result where F: de::Error { - ContentVisitor::new().visit_i16(value).map(TagOrContent::Content) + ContentVisitor.visit_i16(value).map(TagOrContent::Content) } fn visit_i32(self, value: i32) -> Result where F: de::Error { - ContentVisitor::new().visit_i32(value).map(TagOrContent::Content) + ContentVisitor.visit_i32(value).map(TagOrContent::Content) } fn visit_i64(self, value: i64) -> Result where F: de::Error { - ContentVisitor::new().visit_i64(value).map(TagOrContent::Content) + ContentVisitor.visit_i64(value).map(TagOrContent::Content) } fn visit_u8(self, value: u8) -> Result where F: de::Error { - ContentVisitor::new().visit_u8(value).map(TagOrContent::Content) + ContentVisitor.visit_u8(value).map(TagOrContent::Content) } fn visit_u16(self, value: u16) -> Result where F: de::Error { - ContentVisitor::new().visit_u16(value).map(TagOrContent::Content) + ContentVisitor.visit_u16(value).map(TagOrContent::Content) } fn visit_u32(self, value: u32) -> Result where F: de::Error { - ContentVisitor::new().visit_u32(value).map(TagOrContent::Content) + ContentVisitor.visit_u32(value).map(TagOrContent::Content) } fn visit_u64(self, value: u64) -> Result where F: de::Error { - ContentVisitor::new().visit_u64(value).map(TagOrContent::Content) + ContentVisitor.visit_u64(value).map(TagOrContent::Content) } fn visit_f32(self, value: f32) -> Result where F: de::Error { - ContentVisitor::new().visit_f32(value).map(TagOrContent::Content) + ContentVisitor.visit_f32(value).map(TagOrContent::Content) } fn visit_f64(self, value: f64) -> Result where F: de::Error { - ContentVisitor::new().visit_f64(value).map(TagOrContent::Content) + ContentVisitor.visit_f64(value).map(TagOrContent::Content) } fn visit_char(self, value: char) -> Result where F: de::Error { - ContentVisitor::new().visit_char(value).map(TagOrContent::Content) + ContentVisitor.visit_char(value).map(TagOrContent::Content) } fn visit_str(self, value: &str) -> Result @@ -347,7 +337,7 @@ impl Visitor for TagOrContentVisitor { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor::new().visit_str(value).map(TagOrContent::Content) + ContentVisitor.visit_str(value).map(TagOrContent::Content) } } @@ -357,7 +347,7 @@ impl Visitor for TagOrContentVisitor { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor::new().visit_string(value).map(TagOrContent::Content) + ContentVisitor.visit_string(value).map(TagOrContent::Content) } } @@ -367,7 +357,7 @@ impl Visitor for TagOrContentVisitor { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor::new().visit_bytes(value).map(TagOrContent::Content) + ContentVisitor.visit_bytes(value).map(TagOrContent::Content) } } @@ -377,84 +367,82 @@ impl Visitor for TagOrContentVisitor { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor::new().visit_byte_buf(value).map(TagOrContent::Content) + ContentVisitor.visit_byte_buf(value).map(TagOrContent::Content) } } fn visit_unit(self) -> Result where F: de::Error { - ContentVisitor::new().visit_unit().map(TagOrContent::Content) + ContentVisitor.visit_unit().map(TagOrContent::Content) } fn visit_none(self) -> Result where F: de::Error { - ContentVisitor::new().visit_none().map(TagOrContent::Content) + ContentVisitor.visit_none().map(TagOrContent::Content) } fn visit_some(self, deserializer: D) -> Result where D: Deserializer { - ContentVisitor::new().visit_some(deserializer).map(TagOrContent::Content) + ContentVisitor.visit_some(deserializer).map(TagOrContent::Content) } fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer { - ContentVisitor::new().visit_newtype_struct(deserializer).map(TagOrContent::Content) + ContentVisitor.visit_newtype_struct(deserializer).map(TagOrContent::Content) } fn visit_seq(self, visitor: V) -> Result where V: SeqVisitor { - ContentVisitor::new().visit_seq(visitor).map(TagOrContent::Content) + ContentVisitor.visit_seq(visitor).map(TagOrContent::Content) } fn visit_map(self, visitor: V) -> Result where V: MapVisitor { - ContentVisitor::new().visit_map(visitor).map(TagOrContent::Content) + ContentVisitor.visit_map(visitor).map(TagOrContent::Content) } fn visit_enum(self, visitor: V) -> Result where V: EnumVisitor { - ContentVisitor::new().visit_enum(visitor).map(TagOrContent::Content) + ContentVisitor.visit_enum(visitor).map(TagOrContent::Content) } } /// Used by generated code to deserialize an internally tagged enum. /// /// Not public API. -pub struct TaggedContent { +pub struct TaggedContent { pub tag: T, - pub content: Content, + pub content: Content, } /// Not public API. -pub struct TaggedContentVisitor { +pub struct TaggedContentVisitor { tag_name: &'static str, tag: PhantomData, - err: PhantomData, } -impl TaggedContentVisitor { +impl TaggedContentVisitor { /// Visitor for the content of an internally tagged enum with the given tag /// name. pub fn new(name: &'static str) -> Self { TaggedContentVisitor { tag_name: name, tag: PhantomData, - err: PhantomData, } } } -impl DeserializeSeed for TaggedContentVisitor +impl DeserializeSeed for TaggedContentVisitor where T: Deserialize { - type Value = TaggedContent; + type Value = TaggedContent; fn deserialize(self, deserializer: D) -> Result where D: Deserializer @@ -465,10 +453,10 @@ impl DeserializeSeed for TaggedContentVisitor } } -impl Visitor for TaggedContentVisitor +impl Visitor for TaggedContentVisitor where T: Deserialize { - type Value = TaggedContent; + type Value = TaggedContent; fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.write_str("any value") @@ -507,9 +495,15 @@ impl Visitor for TaggedContentVisitor } } +/// Not public API +pub struct ContentDeserializer { + content: Content, + err: PhantomData, +} + /// Used when deserializing an internally tagged enum because the content will /// be used exactly once. -impl Deserializer for Content +impl Deserializer for ContentDeserializer where E: de::Error { type Error = E; @@ -517,8 +511,8 @@ impl Deserializer for Content fn deserialize(self, visitor: V) -> Result where V: Visitor { - match self { - Content::Bool(v, _) => visitor.visit_bool(v), + match self.content { + Content::Bool(v) => visitor.visit_bool(v), Content::U8(v) => visitor.visit_u8(v), Content::U16(v) => visitor.visit_u16(v), Content::U32(v) => visitor.visit_u32(v), @@ -533,8 +527,8 @@ impl Deserializer for Content Content::String(v) => visitor.visit_string(v), Content::Unit => visitor.visit_unit(), Content::None => visitor.visit_none(), - Content::Some(v) => visitor.visit_some(*v), - Content::Newtype(v) => visitor.visit_newtype_struct(*v), + Content::Some(v) => visitor.visit_some(v.into_deserializer()), + Content::Newtype(v) => visitor.visit_newtype_struct(v.into_deserializer()), Content::Seq(v) => { let seq = v.into_iter(); let mut seq_visitor = de::value::SeqDeserializer::new(seq); @@ -556,9 +550,9 @@ impl Deserializer for Content fn deserialize_option(self, visitor: V) -> Result where V: Visitor { - match self { + match self.content { Content::None => visitor.visit_none(), - Content::Some(v) => visitor.visit_some(*v), + Content::Some(v) => visitor.visit_some(v.into_deserializer()), Content::Unit => visitor.visit_unit(), _ => visitor.visit_some(self) } @@ -577,19 +571,28 @@ impl Deserializer for Content } } -impl de::value::ValueDeserializer for Content +impl de::value::ValueDeserializer for Content where E: de::Error { - type Deserializer = Self; + type Deserializer = ContentDeserializer; - fn into_deserializer(self) -> Self { - self + fn into_deserializer(self) -> Self::Deserializer { + ContentDeserializer { + content: self, + err: PhantomData, + } } } +/// Not public API. +pub struct ContentRefDeserializer<'a, E> { + content: &'a Content, + err: PhantomData, +} + /// Used when deserializing an untagged enum because the content may need to be /// used more than once. -impl<'a, E> Deserializer for &'a Content +impl<'a, E> Deserializer for ContentRefDeserializer<'a, E> where E: de::Error { type Error = E; @@ -597,8 +600,8 @@ impl<'a, E> Deserializer for &'a Content fn deserialize(self, visitor: V) -> Result where V: Visitor { - match *self { - Content::Bool(v, _) => visitor.visit_bool(v), + match *self.content { + Content::Bool(v) => visitor.visit_bool(v), Content::U8(v) => visitor.visit_u8(v), Content::U16(v) => visitor.visit_u16(v), Content::U32(v) => visitor.visit_u32(v), @@ -613,8 +616,8 @@ impl<'a, E> Deserializer for &'a Content Content::String(ref v) => visitor.visit_str(v), Content::Unit => visitor.visit_unit(), Content::None => visitor.visit_none(), - Content::Some(ref v) => visitor.visit_some(&**v), - Content::Newtype(ref v) => visitor.visit_newtype_struct(&**v), + Content::Some(ref v) => visitor.visit_some((&**v).into_deserializer()), + Content::Newtype(ref v) => visitor.visit_newtype_struct((&**v).into_deserializer()), Content::Seq(ref v) => { let seq = v.into_iter(); let mut seq_visitor = de::value::SeqDeserializer::new(seq); @@ -636,9 +639,9 @@ impl<'a, E> Deserializer for &'a Content fn deserialize_option(self, visitor: V) -> Result where V: Visitor { - match *self { + match *self.content { Content::None => visitor.visit_none(), - Content::Some(ref v) => visitor.visit_some(&**v), + Content::Some(ref v) => visitor.visit_some((&**v).into_deserializer()), Content::Unit => visitor.visit_unit(), _ => visitor.visit_some(self) } @@ -657,13 +660,16 @@ impl<'a, E> Deserializer for &'a Content } } -impl<'a, E> de::value::ValueDeserializer for &'a Content +impl<'a, E> de::value::ValueDeserializer for &'a Content where E: de::Error { - type Deserializer = Self; + type Deserializer = ContentRefDeserializer<'a, E>; - fn into_deserializer(self) -> Self { - self + fn into_deserializer(self) -> Self::Deserializer { + ContentRefDeserializer { + content: self, + err: PhantomData, + } } }