diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 7ff92104..0a5c487d 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1138,12 +1138,10 @@ pub trait Deserializer<'de>: Sized { fn private_deserialize_internally_tagged_enum( self, visitor: V, - tag: &'static str, ) -> Result where V: Visitor<'de>, { - let _ = tag; self.deserialize_any(visitor) } } diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 6a2ccff1..58972f88 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -2719,15 +2719,13 @@ where fn private_deserialize_internally_tagged_enum( self, visitor: V, - tag: &'static str, ) -> Result where V: Visitor<'de>, { visitor.visit_map(FlatInternallyTaggedAccess { iter: self.0.iter_mut(), - pending: Pending::None, - tag: tag, + pending: None, _marker: PhantomData, }) } @@ -2806,18 +2804,10 @@ where #[cfg(any(feature = "std", feature = "alloc"))] pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> { iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, - pending: Pending<'a, 'de>, - tag: &'static str, + pending: Option<&'a Content<'de>>, _marker: PhantomData, } -#[cfg(any(feature = "std", feature = "alloc"))] -enum Pending<'a, 'de: 'a> { - Content(Content<'de>), - ContentRef(&'a Content<'de>), - None, -} - #[cfg(any(feature = "std", feature = "alloc"))] impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E> where @@ -2830,32 +2820,13 @@ where T: DeserializeSeed<'de>, { while let Some(item) = self.iter.next() { - let is_tag = match *item { - Some((ref key, _)) => key.as_str().map_or(false, |key| key == self.tag), - None => continue, - }; - - let ret = if is_tag { - let (key, content) = item.take().unwrap(); - self.pending = Pending::Content(content); - - // Could use `ContentDeserializer::new(key)` here but we prefer - // to avoid instantiating `seed.deserialize` twice with - // different Deserializer type parameters. The visitor that - // decides which variant we are looking at does not benefit from - // having ownership of this string. - seed.deserialize(ContentRefDeserializer::new(&key)) - } else { - // Do not take(), instead borrow this entry. The internally - // tagged enum does its own buffering so we can't tell whether - // this entry is going to be consumed. Borrowing here leaves the - // entry available for later flattened fields. - let (ref key, ref content) = *item.as_ref().unwrap(); - self.pending = Pending::ContentRef(content); - seed.deserialize(ContentRefDeserializer::new(key)) - }; - - return ret.map(Some); + // Do not take(), instead borrow this entry. The internally tagged + // enum does its own buffering so we can't tell whether this entry + // is going to be consumed. Borrowing here leaves the entry + // available for later flattened fields. + let (ref key, ref content) = *item.as_ref().unwrap(); + self.pending = Some(content); + return seed.deserialize(ContentRefDeserializer::new(key)).map(Some); } Ok(None) } @@ -2864,18 +2835,9 @@ where where T: DeserializeSeed<'de>, { - match mem::replace(&mut self.pending, Pending::None) { - Pending::Content(value) => { - // Could use `ContentDeserializer::new(value)` here but we - // prefer to avoid instantiating `seed.deserialize` twice with - // different Deserializer type parameters. Flatten and internal - // tagging are both relatively slow at runtime anyway so the - // improvement in compile time is more important here than - // potentially saving some string copies. - seed.deserialize(ContentRefDeserializer::new(&value)) - } - Pending::ContentRef(value) => seed.deserialize(ContentRefDeserializer::new(value)), - Pending::None => panic!("value is missing"), + match self.pending.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => panic!("value is missing"), } } } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index c8b1e7f3..f1a37b85 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1195,8 +1195,7 @@ fn deserialize_internally_tagged_enum( let __tagged = try!(_serde::Deserializer::private_deserialize_internally_tagged_enum( __deserializer, - _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag), - #tag)); + _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); match __tagged.tag { #(#variant_arms)*