mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-09 11:05:19 -05:00
de(map): fix map deserialization
- This allows extra Attribute nodes to end up in a HashMap
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use serde::de::{DeserializeSeed, MapAccess};
|
||||
|
||||
use de::{Deserializer, Result};
|
||||
use error::Error;
|
||||
use error::{Error, KbinErrorKind};
|
||||
use node_types::StandardType;
|
||||
|
||||
pub struct Map<'a, 'de: 'a> {
|
||||
@@ -14,6 +14,7 @@ impl<'de, 'a> Map<'a, 'de> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIX THIS, it's pretty broken, but it will deserialize correctly
|
||||
impl<'de, 'a> MapAccess<'de> for Map<'a, 'de> {
|
||||
type Error = Error;
|
||||
|
||||
@@ -25,18 +26,42 @@ impl<'de, 'a> MapAccess<'de> for Map<'a, 'de> {
|
||||
let (node_type, _is_array) = self.de.reader.read_node_type()?;
|
||||
debug!("<Map as MapAccess>::next_key_seed() => node_type: {:?}", node_type);
|
||||
|
||||
if node_type == StandardType::NodeEnd {
|
||||
if node_type == StandardType::NodeEnd ||
|
||||
node_type == StandardType::FileEnd
|
||||
{
|
||||
trace!("<Map as MapAccess>::next_key_seed() => end of map");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
let key = seed.deserialize(&mut *self.de).map(Some)?;
|
||||
|
||||
self.de.node_stack.push(node_type);
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
|
||||
where V: DeserializeSeed<'de>
|
||||
{
|
||||
debug!("--> <Map as MapAccess>::next_value_seed()");
|
||||
seed.deserialize(&mut *self.de)
|
||||
let value = seed.deserialize(&mut *self.de)?;
|
||||
|
||||
let popped = self.de.node_stack.pop();
|
||||
debug!("<Map as MapAccess>::next_value_seed() => popped: {:?}, node_stack: {:?}", popped, self.de.node_stack);
|
||||
|
||||
// Consume the NodeEnd
|
||||
match popped {
|
||||
Some(StandardType::Attribute) |
|
||||
Some(StandardType::NodeStart) => {},
|
||||
Some(_) => {
|
||||
let (node_type, _is_array) = self.de.reader.read_node_type()?;
|
||||
if node_type != StandardType::NodeEnd {
|
||||
return Err(KbinErrorKind::TypeMismatch(*StandardType::NodeEnd, *node_type).into());
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,14 +286,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_struct(name: {:?})", name);
|
||||
trace!("Deserializer::deserialize_struct() => fields: {:?}", fields);
|
||||
trace!("Deserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields);
|
||||
|
||||
// The `NodeStart` event is consumed by `deserialize_identifier` when
|
||||
// reading the parent struct, don't consume the next event.
|
||||
if self.first_struct {
|
||||
let (node_type, _, name) = self.read_node_with_name()?;
|
||||
debug!("Deserializer::deserialize_struct() => node_type: {:?}, name: {:?}", node_type, name);
|
||||
debug!("Deserializer::deserialize_struct() => node_type: {:?}, name: {:?}, last identifier: {:?}", node_type, name, self.reader.last_identifier());
|
||||
|
||||
// Sanity check
|
||||
if node_type != StandardType::NodeStart {
|
||||
@@ -317,10 +316,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_identifier()");
|
||||
let (node_type, _) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?;
|
||||
trace!("Deserializer::deserialize_identifier() => last node type: {:?}", node_type);
|
||||
|
||||
let name = self.reader.read_node_identifier()?;
|
||||
debug!("Deserializer::deserialize_identifier() => name: {}", name);
|
||||
// Prefix Attribute node identifier's with "attr_" to help the serializer
|
||||
let name = match (node_type, self.reader.read_node_identifier()?) {
|
||||
(StandardType::Attribute, name) => format!("attr_{}", name),
|
||||
(StandardType::NodeStart, name) => {
|
||||
self.first_struct = false;
|
||||
name
|
||||
},
|
||||
(_, name) => name,
|
||||
};
|
||||
debug!("Deserializer::deserialize_identifier() => name: '{}'", name);
|
||||
|
||||
// Do not use `deserialize_string`! That reads from the data buffer and
|
||||
// this reads a sixbit string from the node buffer
|
||||
|
||||
Reference in New Issue
Block a user