de(seq): fix bug deserializing regular arrays

This commit is contained in:
Matt Bilker
2018-09-11 17:23:37 +00:00
parent 3c57e733ed
commit 37e4d71ed5
2 changed files with 17 additions and 11 deletions

View File

@@ -70,7 +70,7 @@ impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> {
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
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<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
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<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>

View File

@@ -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<Value>,
},
}
@@ -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)
},
}