From 37e4d71ed5f4bb43ff024755d83849c0829df14e Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Tue, 11 Sep 2018 17:23:37 +0000 Subject: [PATCH] de(seq): fix bug deserializing regular arrays --- src/de/collection.rs | 20 +++++++++++++++----- src/de/seq.rs | 8 ++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/de/collection.rs b/src/de/collection.rs index bf6abbd..961e242 100644 --- a/src/de/collection.rs +++ b/src/de/collection.rs @@ -70,7 +70,7 @@ impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> { fn deserialize_any(mut self, visitor: V) -> Result where V: Visitor<'de> { - let collection = self.pop_node()?; + let mut collection = self.pop_node()?; let base = collection.base(); let node_type = base.node_type; @@ -80,14 +80,14 @@ impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> { warn_attributes(&collection)?; trace!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array); - return visitor.visit_seq(Seq::new(&mut self.collection, is_array)?); + return visitor.visit_seq(Seq::new(&mut collection, true)?); } match node_type { StandardType::NodeStart => { debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => deserializing node", node_type, is_array); - let node = self.collection.as_node(); + let node = collection.as_node(); debug!("NodeCollectionDeserializer::deserialize_any(node_type: {:?}, is_array: {}) => node: {:?}", node_type, is_array, node); let marshal = Marshal::with_node(StandardType::NodeStart, node?); @@ -157,15 +157,25 @@ impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> { Err(Error::StaticMessage("newtype struct deserialization is not supported")) } + /// This will deserialize as a sequence of nodes if the first child node of + /// `self.collection` has `is_array == false`. Else, it will pop the first + /// child node and deserialize it as an array. + /// + /// This is a compromise to allow struct sequences but also allow arrays of value. fn deserialize_seq(mut self, visitor: V) -> Result where V: Visitor<'de> { - let base = self.collection.base(); + let base = self.collection.children().front().ok_or(KbinErrorKind::InvalidState)?.base(); let node_type = base.node_type; let is_array = base.is_array; debug!("NodeCollectionDeserializer::deserialize_seq(node_type: {:?}, is_array: {})", node_type, is_array); - visitor.visit_seq(Seq::new(&mut self.collection, false)?) + if is_array { + let mut collection = self.pop_node_warn()?; + visitor.visit_seq(Seq::new(&mut collection, true)?) + } else { + visitor.visit_seq(Seq::new(&mut self.collection, false)?) + } } fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result diff --git a/src/de/seq.rs b/src/de/seq.rs index 760e788..1d48434 100644 --- a/src/de/seq.rs +++ b/src/de/seq.rs @@ -3,7 +3,6 @@ use std::collections::VecDeque; use serde::de::{DeserializeSeed, IntoDeserializer, SeqAccess}; use de::collection::NodeCollectionDeserializer; -use de::custom::Custom; use error::{Error, KbinErrorKind}; use node::NodeCollection; use node_types::StandardType; @@ -14,7 +13,6 @@ enum SequenceMode { known_identifier: String, }, Value { - node_type: StandardType, values: VecDeque, }, } @@ -31,7 +29,6 @@ impl<'de, 'a> Seq<'a, 'de> { let seq_mode = if is_array { let base = collection.base(); - let node_type = base.node_type; let value = base.value()?; let values = if let Value::Array(node_type, values) = value { debug!("Seq::new(is_array: {}) => len: {}", is_array, values.len()); @@ -45,7 +42,7 @@ impl<'de, 'a> Seq<'a, 'de> { return Err(KbinErrorKind::InvalidState.into()); }; - SequenceMode::Value { node_type, values } + SequenceMode::Value { values } } else { let child = collection.children().front().ok_or(KbinErrorKind::InvalidState)?; let known_identifier = child.base().key()?.ok_or(KbinErrorKind::InvalidState)?; @@ -107,7 +104,7 @@ impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> { let de = NodeCollectionDeserializer::new(&mut self.collection); seed.deserialize(de).map(Some) }, - SequenceMode::Value { node_type, ref mut values } => { + SequenceMode::Value { ref mut values } => { let value = match values.pop_front() { Some(v) => v, None => { @@ -118,7 +115,6 @@ impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> { }; let de = value.into_deserializer(); - let de = Custom::new(de, node_type); seed.deserialize(de).map(Some) }, }