node(extra): use Marshal to marshal nodes from the Deserializer

This commit is contained in:
Matt Bilker
2018-08-30 23:19:44 -04:00
parent bfeb3d8559
commit b3586cbed7
2 changed files with 67 additions and 26 deletions

View File

@@ -2,9 +2,10 @@ use std::result::Result as StdResult;
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
use failure::ResultExt;
use serde::de::{self, Deserialize, Visitor};
use serde::de::{self, Deserialize, DeserializeSeed, IntoDeserializer, Visitor};
use error::{Error, KbinErrorKind};
use node::{Marshal, Node};
use node_types::StandardType;
use reader::Reader;
@@ -157,6 +158,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
};
}
// Only deserialize identifiers in `Key` mode
if self.read_mode == ReadMode::Key {
return self.deserialize_identifier(visitor);
}
let value = match node_type {
/*
StandardType::Attribute => self.deserialize_string(visitor),
@@ -170,9 +176,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
StandardType::S16 => self.deserialize_i16(visitor),
StandardType::S32 => self.deserialize_i32(visitor),
StandardType::S64 => self.deserialize_i64(visitor),
*/
StandardType::Binary => visitor.visit_bytes(self.reader.read_bytes()?),
/*
StandardType::Ip4 => {
let old_read_mode = self.set_read_mode(ReadMode::Array);
let value = visitor.visit_enum(Custom::new(self, node_type))?;
@@ -181,13 +185,26 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
},
StandardType::Boolean => self.deserialize_bool(visitor),
*/
StandardType::NodeStart => self.deserialize_map(visitor),
StandardType::NodeStart => {
debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => deserializing node", node_type, is_array);
let node = Node::deserialize(self);
debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => node: {:?}", node_type, is_array, node);
let marshal = Marshal::with_node(StandardType::NodeStart, node?);
visitor.visit_newtype_struct(marshal.into_deserializer())
},
/*
StandardType::NodeEnd => {
// Move `deserialize_any` on to the next node
let _ = self.reader.read_node_type()?;
self.deserialize_any(visitor)
},
_ => visitor.visit_enum(Custom::new(self, node_type)),
*/
_ => {
let value = node_type.deserialize(self)?;
debug!("Deserializer::deserialize_any(node_type: {:?}, is_array: {}) => value: {:?}", node_type, is_array, value);
let marshal = Marshal::with_value(node_type, value);
visitor.visit_newtype_struct(marshal.into_deserializer())
},
};
value
}
@@ -236,15 +253,17 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
}
}
forward_to_deserialize_any! {
bytes
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_bytes()");
visitor.visit_bytes(self.reader.read_bytes()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where V: Visitor<'de>
{
trace!("Deserializer::deserialize_byte_buf()");
visitor.visit_byte_buf(self.reader.read_bytes()?.to_vec())
}

View File

@@ -2,9 +2,9 @@ use std::fmt;
use serde::de::{self, Deserialize, Error, MapAccess, Visitor};
use node::ExtraNodes;
use node::de::{NodeSeed, NodeStart, NodeVisitor};
use node_types::StandardType;
use node::Node;
use node::extra::ExtraNodes;
use node::marshal::{Marshal, MarshalValue};
use value::Value;
impl<'de> Deserialize<'de> for ExtraNodes {
@@ -18,7 +18,7 @@ impl<'de> Deserialize<'de> for ExtraNodes {
type Value = ExtraNodes;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid map of kbin nodes")
formatter.write_str("any valid map of kbin nodes (for ExtraNodes)")
}
#[inline]
@@ -29,26 +29,48 @@ impl<'de> Deserialize<'de> for ExtraNodes {
let mut extra = ExtraNodes::new();
while let Some(NodeStart { key, node_type }) = try!(map.next_key_seed(NodeSeed)) {
debug!("ExtraNodesVisitor::visit_map() => key: {:?}, node_type: {:?}", key, node_type);
loop {
let key = match map.next_key::<String>() {
Ok(Some(s)) => s,
Ok(None) => break,
Err(e) => {
error!("ExtraNodesVisitor::visit_map() => error: {:?}", e);
return Err(e);
},
};
debug!("ExtraNodesVisitor::visit_map() => key: {:?}", key);
match node_type {
StandardType::Attribute => {
let value = try!(map.next_value());
debug!("ExtraNodesVisitor::visit_map() => value: {:?}", value);
let marshal: Marshal = try!(map.next_value());
debug!("ExtraNodesVisitor::visit_map() => marshal: {:?}", marshal);
let value = marshal.into_inner();
if key.starts_with("attr_") {
let key = String::from(&key["attr_".len()..]);
debug!("ExtraNodesVisitor::visit_map() => found attribute, key: {:?}, value: {:?}", key, value);
if let Some(value) = value.as_value() {
if let Value::Attribute(s) = value {
let key = String::from(&key["attr_".len()..]);
extra.attributes.insert(key, s);
extra.set_attr(key, s);
} else {
return Err(A::Error::custom("`Attribute` node must have `Value::Attribute` value"));
}
},
_ => {
let node = NodeVisitor::map_to_node(node_type, &key, &mut map)?;
debug!("ExtraNodesVisitor::visit_map() => node: {:?}", node);
},
};
} else {
return Err(A::Error::custom("`Marshal` must contain `Value` for attribute"));
}
} else {
/*
let node = NodeVisitor::map_to_node(node_type, &key, &mut map)?;
debug!("ExtraNodesVisitor::visit_map() => node: {:?}", node);
*/
match value {
MarshalValue::Value(value) => extra.insert(key.clone(), Node::with_value(key, value)),
MarshalValue::Node(mut node) => {
node.key = key.clone();
extra.insert(key, node)
},
};
}
}
Ok(extra)