mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-09 19:15:27 -05:00
de: use NodeCollection and NodeDefinition for deserialization
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kbinxml"
|
||||
version = "0.9.2"
|
||||
version = "0.10.1"
|
||||
authors = ["Matt Bilker <me@mbilker.us>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::net::Ipv4Addr;
|
||||
use std::str;
|
||||
|
||||
use failure::Fail;
|
||||
use kbinxml::{ExtraNodes, Ip4Addr, KbinXml, Node, Options, Printer, from_bytes, to_bytes};
|
||||
use kbinxml::{ExtraNodes, KbinXml, Node, Options, Printer, from_bytes, to_bytes};
|
||||
use minidom::Element;
|
||||
use quick_xml::Writer;
|
||||
|
||||
@@ -27,7 +27,7 @@ pub struct Testing2 {
|
||||
vu: Vec<u8>,
|
||||
opt: Option<u8>,
|
||||
opt2: Option<u8>,
|
||||
ip: Ip4Addr,
|
||||
ip: Ipv4Addr,
|
||||
|
||||
#[serde(flatten)]
|
||||
extra: ExtraNodes,
|
||||
@@ -140,7 +140,9 @@ fn main() -> std::io::Result<()> {
|
||||
|
||||
let value = from_bytes::<Node>(&contents);
|
||||
match &value {
|
||||
Ok(obj2) => eprintln!("obj2: {:#?}", obj2),
|
||||
Ok(obj2) => {
|
||||
eprintln!("obj2: {:#?}", obj2);
|
||||
},
|
||||
Err(e) => eprintln!("Unable to parse generated kbin back to `Value`: {:#?}", e),
|
||||
};
|
||||
} else {
|
||||
@@ -169,7 +171,7 @@ fn main() -> std::io::Result<()> {
|
||||
vu: vec![33, 255, 254],
|
||||
opt: None,
|
||||
opt2: Some(111),
|
||||
ip: Ip4Addr::new(Ipv4Addr::new(127, 0, 0, 1)),
|
||||
ip: Ipv4Addr::new(127, 0, 0, 1),
|
||||
extra: ExtraNodes::new(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -85,6 +85,7 @@ impl<'buf> ByteBufferRead<'buf> {
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn read_str(&mut self, encoding: EncodingType) -> Result<String> {
|
||||
let data = self.buf_read()?;
|
||||
let data = strip_trailing_null_bytes(data);
|
||||
@@ -92,6 +93,7 @@ impl<'buf> ByteBufferRead<'buf> {
|
||||
|
||||
encoding.decode_bytes(data)
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get(&mut self, size: u32) -> Result<&'buf [u8]> {
|
||||
let data = self.buf_read_size(size as usize)?;
|
||||
|
||||
247
src/de/collection.rs
Normal file
247
src/de/collection.rs
Normal file
@@ -0,0 +1,247 @@
|
||||
use serde::de::{self, IntoDeserializer, Visitor};
|
||||
|
||||
use de::custom::Custom;
|
||||
use de::definition::NodeDefinitionDeserializer;
|
||||
use de::node_contents::NodeContents;
|
||||
use de::seq::Seq;
|
||||
use de::structure::Struct;
|
||||
use error::{Error, KbinErrorKind};
|
||||
use node::{Marshal, NodeCollection};
|
||||
use node_types::StandardType;
|
||||
|
||||
fn warn_attributes<'de>(value: &NodeCollection<'de>) -> Result<(), Error> {
|
||||
for attr in value.attributes() {
|
||||
let key = attr.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
let value = attr.value()?;
|
||||
warn!("Ignoring Attribute {} = {}", key, value);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct NodeCollectionDeserializer<'a, 'de: 'a> {
|
||||
pub(crate) collection: &'a mut NodeCollection<'de>,
|
||||
}
|
||||
|
||||
impl<'de, 'a> NodeCollectionDeserializer<'a, 'de> {
|
||||
pub fn new(collection: &'a mut NodeCollection<'de>) -> Self {
|
||||
trace!("NodeCollectionDeserializer::new() => attributes len: {}, children len: {}, base: {}",
|
||||
collection.attributes().len(),
|
||||
collection.children().len(),
|
||||
collection.base());
|
||||
|
||||
Self { collection }
|
||||
}
|
||||
|
||||
fn pop_node(&mut self) -> Result<NodeCollection<'de>, Error> {
|
||||
self.collection.children_mut().pop_front().ok_or(KbinErrorKind::InvalidState.into())
|
||||
}
|
||||
|
||||
fn pop_node_warn(&mut self) -> Result<NodeCollection<'de>, Error> {
|
||||
let value = self.pop_node()?;
|
||||
warn_attributes(&value)?;
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! forward_to_definition_deserializer {
|
||||
($($method:ident)*) => {
|
||||
$(
|
||||
#[inline]
|
||||
fn $method<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!(concat!("NodeCollectionDeserializer::", stringify!($method), "()"));
|
||||
let collection = self.pop_node()?;
|
||||
NodeDefinitionDeserializer::new(collection.base()).$method(visitor)
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl<'de, 'a> de::Deserializer<'de> for NodeCollectionDeserializer<'a, 'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn is_human_readable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let collection = self.pop_node()?;
|
||||
|
||||
let base = collection.base();
|
||||
let node_type = base.node_type;
|
||||
let is_array = base.is_array;
|
||||
|
||||
if is_array {
|
||||
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)?);
|
||||
}
|
||||
|
||||
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();
|
||||
debug!("NodeCollectionDeserializer::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())
|
||||
},
|
||||
_ => {
|
||||
warn_attributes(&collection)?;
|
||||
|
||||
let value = base.value()?;
|
||||
debug!("NodeCollectionDeserializer::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())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
ignored_any
|
||||
}
|
||||
|
||||
forward_to_definition_deserializer! {
|
||||
deserialize_bool
|
||||
deserialize_i8
|
||||
deserialize_i16
|
||||
deserialize_i32
|
||||
deserialize_i64
|
||||
deserialize_i128
|
||||
deserialize_u8
|
||||
deserialize_u16
|
||||
deserialize_u32
|
||||
deserialize_u64
|
||||
deserialize_u128
|
||||
deserialize_f32
|
||||
deserialize_f64
|
||||
deserialize_char
|
||||
deserialize_str
|
||||
deserialize_string
|
||||
deserialize_bytes
|
||||
deserialize_byte_buf
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_option()");
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_unit()");
|
||||
Err(Error::StaticMessage("unit deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_unit_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("unit struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_newtype_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let base = self.collection.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)?)
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_tuple(len: {})", len);
|
||||
|
||||
let collection = self.pop_node_warn()?;
|
||||
NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple(len, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(mut self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len);
|
||||
|
||||
let base = self.collection.base();
|
||||
let node_type = base.node_type;
|
||||
|
||||
match name {
|
||||
"__key" => {
|
||||
let key = base.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
let de = key.into_deserializer();
|
||||
visitor.visit_enum(Custom::new(de, node_type))
|
||||
},
|
||||
"__value" => {
|
||||
debug!("NodeCollectionDeserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type);
|
||||
|
||||
let mut collection = self.pop_node()?;
|
||||
visitor.visit_map(NodeContents::new(&mut collection))
|
||||
},
|
||||
_ => {
|
||||
let collection = self.pop_node_warn()?;
|
||||
NodeDefinitionDeserializer::new(collection.base()).deserialize_tuple_struct(name, len, visitor)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_map()");
|
||||
|
||||
let mut collection = self.pop_node()?;
|
||||
visitor.visit_map(Struct::new(&mut collection))
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(mut self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields);
|
||||
|
||||
let mut collection = self.pop_node()?;
|
||||
let value = visitor.visit_map(Struct::new(&mut collection))?;
|
||||
|
||||
let keys: Vec<_> = self.collection.children().iter()
|
||||
.filter_map(|x| x.base().key().ok())
|
||||
.collect();
|
||||
trace!("NodeCollectionDeserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants);
|
||||
Err(Error::StaticMessage("enum deserialization not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeCollectionDeserializer::deserialize_identifier()");
|
||||
|
||||
// Delegate identifier deserialization to `NodeDefinitionDeserializer`
|
||||
NodeDefinitionDeserializer::new(self.collection.base()).deserialize_identifier(visitor)
|
||||
}
|
||||
}
|
||||
@@ -73,9 +73,18 @@ impl<'de, D> Deserializer<'de> for Custom<D>
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
/// Passthrough identifier deserialization so regular deserialization still works
|
||||
#[inline]
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, D::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("<Custom as Deserializer>::deserialize_identifier(node_type: {:?})", self.node_type);
|
||||
self.de.deserialize_identifier(visitor)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
|
||||
string bytes byte_buf option unit unit_struct newtype_struct seq
|
||||
tuple tuple_struct map struct enum identifier ignored_any
|
||||
tuple tuple_struct map struct enum ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
228
src/de/definition.rs
Normal file
228
src/de/definition.rs
Normal file
@@ -0,0 +1,228 @@
|
||||
use serde::de::{self, IntoDeserializer, Visitor};
|
||||
|
||||
use de::custom::Custom;
|
||||
use de::seq::Seq;
|
||||
use error::{Error, KbinErrorKind};
|
||||
use node::{Marshal, NodeCollection, NodeDefinition};
|
||||
use node_types::StandardType;
|
||||
use value::Value;
|
||||
|
||||
pub struct NodeDefinitionDeserializer<'de> {
|
||||
definition: NodeDefinition<'de>,
|
||||
}
|
||||
|
||||
impl<'de> NodeDefinitionDeserializer<'de> {
|
||||
pub fn new(definition: NodeDefinition<'de>) -> Self {
|
||||
trace!("NodeDefinitionDeserializer::new(definition: {})", definition);
|
||||
|
||||
Self { definition }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! auto_deserialize {
|
||||
($($method:ident $konst:ident $visit_method:ident)*) => {
|
||||
$(
|
||||
#[inline]
|
||||
fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!(concat!("NodeDefinitionDeserializer::", stringify!($method), "()"));
|
||||
|
||||
match self.definition.value() {
|
||||
Ok(Value::$konst(value)) => visitor.$visit_method(value),
|
||||
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl<'de> de::Deserializer<'de> for NodeDefinitionDeserializer<'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn is_human_readable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let node_type = self.definition.node_type;
|
||||
let is_array = self.definition.is_array;
|
||||
trace!("NodeDefinitionDeserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array);
|
||||
|
||||
// Construct a shim `NodeCollection` for `Seq` if we are deserializing an
|
||||
// array value
|
||||
if is_array {
|
||||
let mut collection = NodeCollection::new(self.definition);
|
||||
return visitor.visit_seq(Seq::new(&mut collection, true)?);
|
||||
}
|
||||
|
||||
let value = match node_type {
|
||||
StandardType::NodeStart => {
|
||||
debug!("NodeDefinitionDeserializer::deserialize_any(unode_type: {:?}, is_array: {})", node_type, is_array);
|
||||
Err(KbinErrorKind::InvalidNodeType(node_type).into())
|
||||
},
|
||||
_ => {
|
||||
let value = self.definition.value()?;
|
||||
debug!("NodeDefinitionDeserializer::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
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
i128 u128 char str
|
||||
seq
|
||||
map struct enum ignored_any
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_bool()");
|
||||
|
||||
match self.definition.value() {
|
||||
Ok(Value::Boolean(b)) => visitor.visit_bool(b),
|
||||
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
auto_deserialize! {
|
||||
deserialize_i8 S8 visit_i8
|
||||
deserialize_i16 S16 visit_i16
|
||||
deserialize_i32 S32 visit_i32
|
||||
deserialize_i64 S64 visit_i64
|
||||
deserialize_u8 U8 visit_u8
|
||||
deserialize_u16 U16 visit_u16
|
||||
deserialize_u32 U32 visit_u32
|
||||
deserialize_u64 U64 visit_u64
|
||||
deserialize_f32 Float visit_f32
|
||||
deserialize_f64 Double visit_f64
|
||||
deserialize_byte_buf Binary visit_byte_buf
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_string()");
|
||||
|
||||
match self.definition.value() {
|
||||
Ok(Value::String(s)) |
|
||||
Ok(Value::Attribute(s)) => visitor.visit_string(s),
|
||||
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_bytes()");
|
||||
|
||||
if self.definition.node_type == StandardType::Binary {
|
||||
match self.definition.value_bytes() {
|
||||
Some(data) => visitor.visit_bytes(data),
|
||||
None => Err(KbinErrorKind::InvalidState.into()),
|
||||
}
|
||||
} else {
|
||||
Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into())
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_option()");
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_unit()");
|
||||
Err(Error::StaticMessage("unit deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_unit_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("unit struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_newtype_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len);
|
||||
|
||||
let node_type = self.definition.node_type;
|
||||
|
||||
match name {
|
||||
"__key" => {
|
||||
let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
let de = key.into_deserializer();
|
||||
visitor.visit_enum(Custom::new(de, node_type))
|
||||
},
|
||||
"__value" => {
|
||||
debug!("NodeDefinitionDeserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type);
|
||||
self.deserialize_any(visitor)
|
||||
},
|
||||
_ => {
|
||||
Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserialize::deserialize_tuple(len: {})", len);
|
||||
|
||||
macro_rules! tuple {
|
||||
($($konst:ident),*) => {
|
||||
match self.definition.value() {
|
||||
$(
|
||||
Ok(value @ Value::$konst(_)) |
|
||||
)*
|
||||
Ok(value @ Value::Ip4(_)) => value.into_deserializer().deserialize_any(visitor),
|
||||
Ok(_) => Err(KbinErrorKind::InvalidNodeType(self.definition.node_type).into()),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tuple! {
|
||||
S8_2, U8_2, S16_2, U16_2, S32_2, U32_2, S64_2, U64_2, Float2, Double2, Boolean2,
|
||||
S8_3, U8_3, S16_3, U16_3, S32_3, U32_3, S64_3, U64_3, Float3, Double3, Boolean3,
|
||||
S8_4, U8_4, S16_4, U16_4, S32_4, U32_4, S64_4, U64_4, Float4, Double4, Boolean4,
|
||||
Vs16, Vu16,
|
||||
Vs8, Vu8, Vb
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("NodeDefinitionDeserializer::deserialize_identifier()");
|
||||
|
||||
let key = self.definition.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
let key = match self.definition.node_type {
|
||||
StandardType::Attribute => format!("attr_{}", key),
|
||||
_ => key,
|
||||
};
|
||||
|
||||
visitor.visit_string(key)
|
||||
}
|
||||
}
|
||||
434
src/de/mod.rs
434
src/de/mod.rs
@@ -1,42 +1,25 @@
|
||||
use std::result::Result as StdResult;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||
use failure::ResultExt;
|
||||
use serde::de::{self, Deserialize, DeserializeSeed, IntoDeserializer, Visitor};
|
||||
use serde::de::{self, Deserialize, Visitor};
|
||||
|
||||
use error::{Error, KbinErrorKind};
|
||||
use node::{Marshal, Node};
|
||||
use node_types::StandardType;
|
||||
use node::NodeCollection;
|
||||
use reader::Reader;
|
||||
|
||||
mod collection;
|
||||
mod custom;
|
||||
mod definition;
|
||||
mod node_contents;
|
||||
mod seq;
|
||||
mod structure;
|
||||
mod tuple;
|
||||
|
||||
use self::custom::Custom;
|
||||
use self::node_contents::NodeContents;
|
||||
use self::seq::Seq;
|
||||
use self::structure::Struct;
|
||||
use self::tuple::TupleBytesDeserializer;
|
||||
|
||||
pub type Result<T> = StdResult<T, Error>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum ReadMode {
|
||||
Key,
|
||||
Single,
|
||||
Array,
|
||||
}
|
||||
|
||||
pub struct Deserializer<'de> {
|
||||
read_mode: ReadMode,
|
||||
node_stack: Vec<(StandardType, bool)>,
|
||||
first_struct: bool,
|
||||
ignore_attributes: bool,
|
||||
|
||||
reader: Reader<'de>,
|
||||
collection: NodeCollection<'de>,
|
||||
}
|
||||
|
||||
pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result<T>
|
||||
@@ -49,77 +32,10 @@ pub fn from_bytes<'a, T>(input: &'a [u8]) -> Result<T>
|
||||
|
||||
impl<'de> Deserializer<'de> {
|
||||
pub fn new(input: &'de [u8]) -> Result<Self> {
|
||||
let reader = Reader::new(input)?;
|
||||
let mut reader = Reader::new(input)?;
|
||||
let collection = NodeCollection::from_iter(&mut reader).ok_or(KbinErrorKind::InvalidState)?;
|
||||
|
||||
Ok(Self {
|
||||
read_mode: ReadMode::Single,
|
||||
node_stack: Vec::new(),
|
||||
first_struct: true,
|
||||
ignore_attributes: true,
|
||||
reader,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn node_stack_last(&self) -> Result<&(StandardType, bool)> {
|
||||
self.node_stack.last()
|
||||
.ok_or(KbinErrorKind::InvalidState.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_read_mode(&mut self, read_mode: ReadMode) -> ReadMode {
|
||||
let old_read_mode = self.read_mode;
|
||||
self.read_mode = read_mode;
|
||||
|
||||
old_read_mode
|
||||
}
|
||||
|
||||
fn read_node_with_name(&mut self) -> Result<(StandardType, bool, String)> {
|
||||
let (node_type, is_array) = self.reader.read_node_type()?;
|
||||
let name = self.reader.read_node_identifier()?;
|
||||
debug!("name: {}", name);
|
||||
|
||||
Ok((node_type, is_array, name))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! de_type {
|
||||
(byte; $method:ident, $visit_method:ident, $standard_type:ident $($cast:tt)*) => {
|
||||
fn $method<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let value = match self.read_mode {
|
||||
ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()),
|
||||
ReadMode::Single => {
|
||||
self.reader.data_buf.get_aligned(*StandardType::$standard_type)?[0] $($cast)*
|
||||
},
|
||||
ReadMode::Array => {
|
||||
self.reader.read_u8().context(KbinErrorKind::DataRead(1))? $($cast)*
|
||||
},
|
||||
};
|
||||
trace!(concat!("Deserializer::", stringify!($method), "() => value: {:?}"), value);
|
||||
|
||||
visitor.$visit_method(value)
|
||||
}
|
||||
};
|
||||
(large; $method:ident, $visit_method:ident, $read_method:ident, $standard_type:ident) => {
|
||||
fn $method<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let value = match self.read_mode {
|
||||
ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()),
|
||||
ReadMode::Single => {
|
||||
let value = self.reader.data_buf.get_aligned(*StandardType::$standard_type)?;
|
||||
BigEndian::$read_method(&value)
|
||||
},
|
||||
ReadMode::Array => {
|
||||
self.reader.data_buf.$read_method::<BigEndian>().context(KbinErrorKind::DataRead(StandardType::$standard_type.size as usize))?
|
||||
},
|
||||
};
|
||||
trace!(concat!("Deserializer::", stringify!($method), "() => value: {:?}"), value);
|
||||
|
||||
visitor.$visit_method(value)
|
||||
}
|
||||
Ok(Self { collection })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,279 +49,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let (node_type, is_array) = self.node_stack_last()
|
||||
.map(|x| *x)
|
||||
.or_else(|_| -> Result<_> {
|
||||
let node = self.reader.peek_node_type()?;
|
||||
self.node_stack.push(node);
|
||||
Ok(node)
|
||||
})?;
|
||||
trace!("Deserializer::deserialize_any(node_type: {:?}, is_array: {})", node_type, is_array);
|
||||
|
||||
// Handle arrays if we are not in array reading mode
|
||||
if is_array {
|
||||
// `Ip4` handling handled by `deserialize_seq`
|
||||
match self.read_mode {
|
||||
ReadMode::Array => {},
|
||||
_ => return self.deserialize_seq(visitor),
|
||||
};
|
||||
}
|
||||
|
||||
// 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),
|
||||
StandardType::String => self.deserialize_string(visitor),
|
||||
StandardType::Binary => visitor.visit_bytes(self.reader.read_bytes()?),
|
||||
StandardType::U8 => self.deserialize_u8(visitor),
|
||||
StandardType::U16 => self.deserialize_u16(visitor),
|
||||
StandardType::U32 => self.deserialize_u32(visitor),
|
||||
StandardType::U64 => self.deserialize_u64(visitor),
|
||||
StandardType::S8 => self.deserialize_i8(visitor),
|
||||
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))?;
|
||||
self.read_mode = old_read_mode;
|
||||
Ok(value)
|
||||
},
|
||||
StandardType::Boolean => self.deserialize_bool(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)
|
||||
},
|
||||
*/
|
||||
_ => {
|
||||
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
|
||||
trace!("Deserializer::deserialize_any()");
|
||||
self.deserialize_map(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_bool()");
|
||||
|
||||
let value = match self.read_mode {
|
||||
ReadMode::Key => return Err(KbinErrorKind::InvalidState.into()),
|
||||
ReadMode::Single => self.reader.data_buf.get_aligned(*StandardType::Boolean)?[0],
|
||||
ReadMode::Array => self.reader.read_u8().context(KbinErrorKind::DataRead(1))?,
|
||||
};
|
||||
trace!("Deserializer::deserialize_bool() => value: {:?}", value);
|
||||
|
||||
let value = match value {
|
||||
0x00 => false,
|
||||
0x01 => true,
|
||||
value => return Err(Error::Message(format!("invalid value for boolean: {0:?} (0x{0:x})", value))),
|
||||
};
|
||||
|
||||
visitor.visit_bool(value)
|
||||
}
|
||||
|
||||
de_type!(byte; deserialize_u8, visit_u8, U8);
|
||||
de_type!(byte; deserialize_i8, visit_i8, S8 as i8);
|
||||
de_type!(large; deserialize_u16, visit_u16, read_u16, U16);
|
||||
de_type!(large; deserialize_i16, visit_i16, read_i16, S16);
|
||||
de_type!(large; deserialize_u32, visit_u32, read_u32, U32);
|
||||
de_type!(large; deserialize_i32, visit_i32, read_i32, S32);
|
||||
de_type!(large; deserialize_u64, visit_u64, read_u64, U64);
|
||||
de_type!(large; deserialize_i64, visit_i64, read_i64, S64);
|
||||
de_type!(large; deserialize_f32, visit_f32, read_f32, Float);
|
||||
de_type!(large; deserialize_f64, visit_f64, read_f64, Double);
|
||||
|
||||
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_char()");
|
||||
Err(Error::StaticMessage("char deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_str()");
|
||||
Err(Error::StaticMessage("borrowed string deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_string() => read_mode: {:?}", self.read_mode);
|
||||
match self.read_mode {
|
||||
ReadMode::Key => self.deserialize_identifier(visitor),
|
||||
_ => visitor.visit_string(self.reader.read_string()?),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_bytes()");
|
||||
visitor.visit_borrowed_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())
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_option()");
|
||||
|
||||
// A `None` value will not occur because it will not be present in the input data
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_unit()");
|
||||
Err(Error::StaticMessage("unit deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_unit_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("unit struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(self, name: &'static str, _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_newtype_struct(name: {:?})", name);
|
||||
Err(Error::StaticMessage("newtype struct deserialization is not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_seq(read_mode: {:?})", self.read_mode);
|
||||
|
||||
let (node_type, _) = *self.node_stack_last()?;
|
||||
|
||||
let value = match node_type {
|
||||
// If the last node type on the stack is a `NodeStart` then we are likely
|
||||
// collecting a list of structs
|
||||
StandardType::NodeStart => visitor.visit_seq(Seq::new(self, None)?)?,
|
||||
|
||||
// Bytes should be deserialized by `deserialize_bytes`
|
||||
StandardType::Binary => self.deserialize_bytes(visitor)?,
|
||||
|
||||
_ => {
|
||||
// TODO: add size check against len
|
||||
let node_size = node_type.size * node_type.count;
|
||||
let size = self.reader.read_u32().context(KbinErrorKind::ArrayLengthRead)?;
|
||||
let arr_count = (size as usize) / node_size;
|
||||
debug!("Deserializer::deserialize_seq() => read array size: {}, arr_count: {}", size, arr_count);
|
||||
|
||||
// Changes to `self.read_mode` must stay here as `next_element_seed` is not
|
||||
// called past the length of the array to reset the read mode
|
||||
let old_read_mode = self.set_read_mode(ReadMode::Array);
|
||||
let value = visitor.visit_seq(Seq::new(self, Some(arr_count))?)?;
|
||||
self.read_mode = old_read_mode;
|
||||
|
||||
// Only realign after the outermost array finishes reading
|
||||
if self.read_mode == ReadMode::Single {
|
||||
self.reader.data_buf.realign_reads(None)?;
|
||||
}
|
||||
|
||||
value
|
||||
},
|
||||
};
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_tuple(len: {})", len);
|
||||
|
||||
let (node_type, is_array) = *self.node_stack_last()?;
|
||||
debug!("Deserializer::deserialize_tuple(len: {}) => node_type: {:?}, is_array: {}", len, node_type, is_array);
|
||||
|
||||
// Handle case where kbin has an array but the Serde output is using a
|
||||
// tuple
|
||||
if is_array && self.read_mode == ReadMode::Single {
|
||||
return self.deserialize_seq(visitor);
|
||||
}
|
||||
|
||||
// Use `get_aligned` to avoid edge cases with the indexors
|
||||
if is_array {
|
||||
let old_read_mode = self.set_read_mode(ReadMode::Array);
|
||||
let value = visitor.visit_seq(Seq::new(self, Some(len))?)?;
|
||||
self.read_mode = old_read_mode;
|
||||
|
||||
// Only realign after the outermost array finishes reading
|
||||
if self.read_mode == ReadMode::Single {
|
||||
self.reader.data_buf.realign_reads(None)?;
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
} else {
|
||||
let data = self.reader.data_buf.get_aligned(*node_type)?;
|
||||
debug!("Deserializer::deserialize_tuple(len: {}) => data: 0x{:02x?}", len, data);
|
||||
|
||||
visitor.visit_seq(TupleBytesDeserializer::new(node_type, data))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_tuple_struct(name: {:?}, len: {})", name, len);
|
||||
|
||||
match name {
|
||||
"__key" => {
|
||||
self.ignore_attributes = false;
|
||||
|
||||
let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?;
|
||||
visitor.visit_enum(Custom::new(self, node_type))
|
||||
},
|
||||
"__value" => {
|
||||
let (node_type, _is_array) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?;
|
||||
debug!("Deserializer::deserialize_tuple_struct(name: {:?}) => node_type: {:?}", name, node_type);
|
||||
|
||||
let value = visitor.visit_map(NodeContents::new(self, node_type))?;
|
||||
self.ignore_attributes = true;
|
||||
|
||||
Ok(value)
|
||||
},
|
||||
_ => {
|
||||
let old_read_mode = self.set_read_mode(ReadMode::Array);
|
||||
let value = visitor.visit_seq(Seq::new(self, Some(len))?)?;
|
||||
self.read_mode = old_read_mode;
|
||||
self.reader.data_buf.realign_reads(None)?;
|
||||
|
||||
Ok(value)
|
||||
},
|
||||
}
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
|
||||
string bytes byte_buf option unit unit_struct newtype_struct seq
|
||||
tuple tuple_struct enum identifier
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
|
||||
@@ -413,20 +64,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
{
|
||||
trace!("Deserializer::deserialize_map()");
|
||||
|
||||
// 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_map() => node_type: {:?}, name: {:?}, last identifier: {:?}", node_type, name, self.reader.last_identifier());
|
||||
let value = visitor.visit_map(Struct::new(&mut self.collection))?;
|
||||
let keys: Vec<_> = self.collection.children().iter()
|
||||
.filter_map(|x| x.base().key().ok())
|
||||
.collect();
|
||||
trace!("Deserializer::deserialize_map() => end, keys: {:?}", keys);
|
||||
|
||||
// Sanity check
|
||||
if node_type != StandardType::NodeStart {
|
||||
return Err(KbinErrorKind::TypeMismatch(*StandardType::NodeStart, *node_type).into());
|
||||
}
|
||||
}
|
||||
self.first_struct = false;
|
||||
|
||||
visitor.visit_map(Struct::new(self))
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
|
||||
@@ -434,47 +78,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
{
|
||||
trace!("Deserializer::deserialize_struct(name: {:?}, fields: {:?})", name, fields);
|
||||
|
||||
let value = self.deserialize_map(visitor)?;
|
||||
trace!("Deserializer::deserialize_struct(name: {:?}) => end", name);
|
||||
let value = visitor.visit_map(Struct::new(&mut self.collection))?;
|
||||
let keys: Vec<_> = self.collection.children().iter()
|
||||
.filter_map(|x| x.base().key().ok())
|
||||
.collect();
|
||||
trace!("Deserializer::deserialize_struct(name: {:?}) => end, keys: {:?}", name, keys);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_enum(name: {:?}, variants: {:?})", name, variants);
|
||||
|
||||
Err(Error::StaticMessage("enum deserialization not supported"))
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
let (node_type, _) = self.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?;
|
||||
trace!("Deserializer::deserialize_identifier() => last node type: {:?}", node_type);
|
||||
|
||||
// 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
|
||||
visitor.visit_string(name)
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
trace!("Deserializer::deserialize_ignored_any()");
|
||||
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess};
|
||||
|
||||
use de::{Custom, Deserializer, ReadMode, Result};
|
||||
use de::{Custom, Result};
|
||||
use de::definition::NodeDefinitionDeserializer;
|
||||
use error::{Error, KbinErrorKind};
|
||||
use node_types::StandardType;
|
||||
use node::NodeCollection;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ReadState {
|
||||
@@ -11,18 +12,16 @@ enum ReadState {
|
||||
}
|
||||
|
||||
pub struct NodeContents<'a, 'de: 'a> {
|
||||
de: &'a mut Deserializer<'de>,
|
||||
node_type: StandardType,
|
||||
collection: &'a mut NodeCollection<'de>,
|
||||
state: ReadState,
|
||||
}
|
||||
|
||||
impl<'de, 'a> NodeContents<'a, 'de> {
|
||||
pub fn new(de: &'a mut Deserializer<'de>, node_type: StandardType) -> Self {
|
||||
trace!("--> NodeContents::new()");
|
||||
pub fn new(collection: &'a mut NodeCollection<'de>) -> Self {
|
||||
trace!("--> NodeContents::new(node_type: {:?})", collection.base().node_type);
|
||||
|
||||
Self {
|
||||
de,
|
||||
node_type,
|
||||
collection,
|
||||
state: ReadState::Value,
|
||||
}
|
||||
}
|
||||
@@ -38,31 +37,22 @@ impl<'de, 'a> MapAccess<'de> for NodeContents<'a, 'de> {
|
||||
|
||||
match self.state {
|
||||
ReadState::Value => {
|
||||
let base = self.collection.base();
|
||||
let de = "__value".into_deserializer();
|
||||
seed.deserialize(Custom::new(de, self.node_type)).map(Some)
|
||||
seed.deserialize(Custom::new(de, base.node_type)).map(Some)
|
||||
},
|
||||
ReadState::Attributes => {
|
||||
let (node_type, _is_array) = self.de.reader.read_node_type()?;
|
||||
debug!("NodeContents::next_key_seed() => node_type: {:?}", node_type);
|
||||
if let Some(attribute) = self.collection.attributes().front() {
|
||||
let key = attribute.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
debug!("<NodeContents as MapAccess>::next_key_seed(state: {:?}) => attribute: {:?}, key: {:?}", self.state, attribute, key);
|
||||
|
||||
match node_type {
|
||||
StandardType::Attribute => {},
|
||||
StandardType::NodeEnd |
|
||||
StandardType::FileEnd => {
|
||||
debug!("<-- <NodeContents as MapAccess>::next_key_seed() => end of map, node stack: {:?}", self.de.node_stack);
|
||||
let de = NodeDefinitionDeserializer::new(*attribute);
|
||||
seed.deserialize(de).map(Some)
|
||||
} else {
|
||||
debug!("<-- <NodeContents as MapAccess>::next_key_seed(state: {:?}) => end of map", self.state);
|
||||
|
||||
return Ok(None);
|
||||
},
|
||||
_ => return Err(KbinErrorKind::InvalidState.into()),
|
||||
};
|
||||
|
||||
let old_read_mode = self.de.set_read_mode(ReadMode::Key);
|
||||
let key = seed.deserialize(&mut *self.de).map(Some)?;
|
||||
self.de.read_mode = old_read_mode;
|
||||
|
||||
self.node_type = node_type;
|
||||
|
||||
Ok(key)
|
||||
Ok(None)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -74,13 +64,24 @@ impl<'de, 'a> MapAccess<'de> for NodeContents<'a, 'de> {
|
||||
|
||||
match self.state {
|
||||
ReadState::Value => {
|
||||
let value = seed.deserialize(&mut *self.de)?;
|
||||
let base = self.collection.base();
|
||||
let de = NodeDefinitionDeserializer::new(base);
|
||||
let value = seed.deserialize(de)?;
|
||||
self.state = ReadState::Attributes;
|
||||
|
||||
Ok(value)
|
||||
},
|
||||
ReadState::Attributes => {
|
||||
seed.deserialize(Custom::new(&mut *self.de, self.node_type))
|
||||
if let Some(attribute) = self.collection.attributes_mut().pop_front() {
|
||||
let node_type = attribute.node_type;
|
||||
let value = attribute.value()?;
|
||||
debug!("<NodeContents as MapAccess>::next_value_seed() => attribute: {:?}, value: {:?}", attribute, value);
|
||||
|
||||
let de = value.into_deserializer();
|
||||
seed.deserialize(Custom::new(de, node_type))
|
||||
} else {
|
||||
Err(KbinErrorKind::InvalidState.into())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
160
src/de/seq.rs
160
src/de/seq.rs
@@ -1,57 +1,65 @@
|
||||
use serde::de::{DeserializeSeed, SeqAccess};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use de::{Deserializer, Result};
|
||||
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;
|
||||
use value::Value;
|
||||
|
||||
enum SequenceMode {
|
||||
Struct {
|
||||
known_identifier: String,
|
||||
},
|
||||
Value {
|
||||
node_type: StandardType,
|
||||
values: VecDeque<Value>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct Seq<'a, 'de: 'a> {
|
||||
de: &'a mut Deserializer<'de>,
|
||||
collection: &'a mut NodeCollection<'de>,
|
||||
index: usize,
|
||||
len: Option<usize>,
|
||||
known_identifier: Option<String>,
|
||||
seq_mode: SequenceMode,
|
||||
}
|
||||
|
||||
impl<'de, 'a> Seq<'a, 'de> {
|
||||
pub fn new(de: &'a mut Deserializer<'de>, len: Option<usize>) -> Result<Self> {
|
||||
trace!("Seq::new(len: {:?})", len);
|
||||
pub fn new(collection: &'a mut NodeCollection<'de>, is_array: bool) -> Result<Self, Error> {
|
||||
trace!("Seq::new(is_array: {})", is_array);
|
||||
|
||||
let known_identifier = if len.is_none() {
|
||||
let value = de.reader.last_identifier().ok_or(KbinErrorKind::InvalidState)?.into();
|
||||
debug!("Seq::new(len: {:?}) => known identifier: {:?}", len, value);
|
||||
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());
|
||||
|
||||
Some(value)
|
||||
if node_type != base.node_type {
|
||||
return Err(KbinErrorKind::TypeMismatch(base.node_type, node_type).into());
|
||||
}
|
||||
|
||||
VecDeque::from(values)
|
||||
} else {
|
||||
return Err(KbinErrorKind::InvalidState.into());
|
||||
};
|
||||
|
||||
SequenceMode::Value { node_type, values }
|
||||
} else {
|
||||
None
|
||||
let child = collection.children().front().ok_or(KbinErrorKind::InvalidState)?;
|
||||
let known_identifier = child.base().key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
debug!("Seq::new(is_array: {}) => known identifier: {:?}", is_array, known_identifier);
|
||||
|
||||
SequenceMode::Struct { known_identifier }
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
de,
|
||||
collection,
|
||||
index: 0,
|
||||
len,
|
||||
known_identifier,
|
||||
seq_mode,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_end(&mut self, node_type: StandardType) -> Result<bool> {
|
||||
// The struct sequence ends when the node identifier has a different name
|
||||
// and the current node type is not `NodeStart` or `NodeEnd` and the last
|
||||
// node was not a `NodeStart` event.
|
||||
//
|
||||
// The should not trigger for struct subfields because those would be
|
||||
// deserialized by the struct deserializer.
|
||||
if node_type != StandardType::NodeStart &&
|
||||
node_type != StandardType::NodeEnd
|
||||
{
|
||||
let node_identifier = self.de.reader.peek_node_identifier()?;
|
||||
let known_identifier = self.known_identifier.as_ref().ok_or(KbinErrorKind::InvalidState)?;
|
||||
if node_identifier.as_str() != known_identifier {
|
||||
debug!("Seq::is_end() => peeked identifier does not equal known identifier: {:?}", known_identifier);
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> {
|
||||
@@ -59,48 +67,60 @@ impl<'de, 'a> SeqAccess<'de> for Seq<'a, 'de> {
|
||||
|
||||
// A len of `None` indicates that the sequence ends when `NodeEnd` is reached
|
||||
// or a different type node is reached.
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where T: DeserializeSeed<'de>
|
||||
{
|
||||
trace!("--> Seq::next_element_seed()");
|
||||
|
||||
if let Some(len) = self.len {
|
||||
if self.index >= len {
|
||||
debug!("Seq::next_element_seed() => out of bounds read, returning None");
|
||||
match self.seq_mode {
|
||||
SequenceMode::Struct { ref known_identifier } => {
|
||||
let base = match self.collection.children().front() {
|
||||
Some(child) => child.base(),
|
||||
None => {
|
||||
debug!("<-- Seq::next_element_seed(mode: Struct) => end of sequence (by `collection.children.front() == None`)");
|
||||
return Ok(None);
|
||||
},
|
||||
};
|
||||
|
||||
return Ok(None);
|
||||
}
|
||||
} else {
|
||||
let (node_type, _is_array) = self.de.reader.peek_node_type()?;
|
||||
let (last_node_type, _is_array) = self.de.reader.last_node_type().ok_or(KbinErrorKind::InvalidState)?;
|
||||
debug!("Seq::next_element_seed() => peeked type: {:?}, last type: {:?}", node_type, self.de.reader.last_node_type());
|
||||
let node_type = base.node_type;
|
||||
debug!("Seq::next_element_seed(mode: Struct) => peeked type: {:?}", node_type);
|
||||
|
||||
if self.is_end(last_node_type)? {
|
||||
debug!("<-- Seq::next_element_seed() => end of sequence (by last read node)");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// If the peeked node is not a `NodeStart` and this isn't the first
|
||||
// element in the list, check the identifier
|
||||
if self.index > 0 {
|
||||
if self.is_end(node_type)? {
|
||||
debug!("<-- Seq::next_element_seed() => end of sequence (by peeked node)");
|
||||
return Ok(None);
|
||||
if self.index > 0 {
|
||||
// The struct sequence ends when the node identifier has a different name
|
||||
// and the current node type is not `NodeStart` or `NodeEnd` and the last
|
||||
// node was not a `NodeStart` event.
|
||||
//
|
||||
// The should not trigger for struct subfields because those would be
|
||||
// deserialized by the struct deserializer.
|
||||
if node_type != StandardType::NodeStart &&
|
||||
node_type != StandardType::NodeEnd
|
||||
{
|
||||
let node_identifier = base.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
if node_identifier.as_str() != known_identifier {
|
||||
debug!("<-- Seq::next_element_seed(mode: Struct) => peeked identifier does not equal known identifier: {:?}", known_identifier);
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.index += 1;
|
||||
|
||||
// `NodeEnd` signals the end of the sequence for a sequence of structs
|
||||
// if all the structs in the sequence have the same type
|
||||
match node_type {
|
||||
// Trigger `deserialize_struct` to consume the `NodeStart` event after
|
||||
// the first element in the struct sequence
|
||||
StandardType::NodeStart => self.de.first_struct = true,
|
||||
StandardType::NodeEnd => return Ok(None),
|
||||
_ => {},
|
||||
};
|
||||
let de = NodeCollectionDeserializer::new(&mut self.collection);
|
||||
seed.deserialize(de).map(Some)
|
||||
},
|
||||
SequenceMode::Value { node_type, ref mut values } => {
|
||||
let value = match values.pop_front() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
debug!("<-- Seq::next_element_seed(mode: Value) => out of bounds read, returning None");
|
||||
|
||||
return Ok(None);
|
||||
},
|
||||
};
|
||||
|
||||
let de = value.into_deserializer();
|
||||
let de = Custom::new(de, node_type);
|
||||
seed.deserialize(de).map(Some)
|
||||
},
|
||||
}
|
||||
self.index += 1;
|
||||
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
use std::marker::PhantomData;
|
||||
use serde::de::{DeserializeSeed, IntoDeserializer, MapAccess};
|
||||
|
||||
use serde::de::{Deserialize, DeserializeSeed, MapAccess};
|
||||
|
||||
use de::{Deserializer, ReadMode, Result};
|
||||
use error::{Error, KbinErrorKind};
|
||||
use de::Custom;
|
||||
use de::collection::NodeCollectionDeserializer;
|
||||
use de::definition::NodeDefinitionDeserializer;
|
||||
use error::Error;
|
||||
use node::NodeCollection;
|
||||
use node_types::StandardType;
|
||||
|
||||
pub struct Struct<'a, 'de: 'a> {
|
||||
de: &'a mut Deserializer<'de>,
|
||||
values_to_consume: usize,
|
||||
collection: &'a mut NodeCollection<'de>,
|
||||
key: Option<String>,
|
||||
}
|
||||
|
||||
impl<'de, 'a> Struct<'a, 'de> {
|
||||
pub fn new(de: &'a mut Deserializer<'de>) -> Self {
|
||||
trace!("--> Struct::new()");
|
||||
pub fn new(collection: &'a mut NodeCollection<'de>) -> Self {
|
||||
let key = collection.base().key().ok().and_then(|v| v);
|
||||
|
||||
trace!("--> Struct::new() => attributes len: {}, children len: {}, base: {}",
|
||||
collection.attributes().len(),
|
||||
collection.children().len(),
|
||||
collection.base());
|
||||
|
||||
Self {
|
||||
de,
|
||||
values_to_consume: 0,
|
||||
collection,
|
||||
key,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,93 +31,57 @@ impl<'de, 'a> Struct<'a, 'de> {
|
||||
impl<'de, 'a> MapAccess<'de> for Struct<'a, 'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
|
||||
where K: DeserializeSeed<'de>
|
||||
{
|
||||
trace!("--> <Struct as MapAccess>::next_key_seed()");
|
||||
debug!("--> <Struct as MapAccess>::next_key_seed()");
|
||||
|
||||
let (node_type, is_array) = self.de.reader.read_node_type()?;
|
||||
debug!("Struct::next_key_seed() => node_type: {:?}", node_type);
|
||||
// First, if the key field is still present, emit the `__node_key` first
|
||||
if self.key.is_some() {
|
||||
let de = "__node_key".into_deserializer();
|
||||
return seed.deserialize(Custom::new(de, StandardType::String)).map(Some);
|
||||
}
|
||||
|
||||
match node_type {
|
||||
StandardType::NodeEnd |
|
||||
StandardType::FileEnd => {
|
||||
// Then if there are attributes left, deserialize them first
|
||||
if let Some(attribute) = self.collection.attributes().front() {
|
||||
let de = NodeDefinitionDeserializer::new(*attribute);
|
||||
return seed.deserialize(de).map(Some);
|
||||
}
|
||||
|
||||
// Else, deserialize the child nodes
|
||||
let mut node = match self.collection.children_mut().front_mut() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
debug!("<-- <Struct as MapAccess>::next_key_seed() => end of map");
|
||||
return Ok(None);
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
let old_read_mode = self.de.set_read_mode(ReadMode::Key);
|
||||
let key = seed.deserialize(&mut *self.de).map(Some)?;
|
||||
self.de.read_mode = old_read_mode;
|
||||
|
||||
match node_type {
|
||||
StandardType::NodeStart => {
|
||||
debug!("Struct::next_key_seed() => got a node start!");
|
||||
},
|
||||
StandardType::Attribute => {
|
||||
debug!("Struct::next_key_seed() => got an attribute!");
|
||||
},
|
||||
_ if self.de.ignore_attributes => {
|
||||
// TODO(mbilker): Fix processing of `Attribute` nodes for non-NodeStart
|
||||
// elements
|
||||
loop {
|
||||
let (node_type, _is_array) = self.de.reader.peek_node_type()?;
|
||||
if node_type == StandardType::Attribute {
|
||||
let _ = self.de.reader.read_node_type()?;
|
||||
warn!("Struct::next_key_seed() => ignoring Attribute node");
|
||||
|
||||
let old_read_mode = self.de.set_read_mode(ReadMode::Key);
|
||||
let key = String::deserialize(&mut *self.de).map(Some)?;
|
||||
self.de.read_mode = old_read_mode;
|
||||
warn!("Struct::next_key_seed() => ignored Attribute key: {:?}", key);
|
||||
|
||||
self.values_to_consume += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Consume the end node and do a sanity check
|
||||
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());
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// Store the current node type on the stack for stateful handling based on
|
||||
// the current node type
|
||||
self.de.node_stack.push((node_type, is_array));
|
||||
|
||||
Ok(key)
|
||||
let de = NodeCollectionDeserializer::new(&mut node);
|
||||
seed.deserialize(de).map(Some)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
|
||||
where V: DeserializeSeed<'de>
|
||||
{
|
||||
debug!("--> <Struct as MapAccess>::next_value_seed()");
|
||||
let value = seed.deserialize(&mut *self.de)?;
|
||||
|
||||
if self.de.ignore_attributes {
|
||||
// Cannot use `next_value_seed` recursively here as it would restart this for loop
|
||||
for _ in 0..self.values_to_consume {
|
||||
warn!("Struct::next_value_seed() => ignoring Attribute node value");
|
||||
let seed = PhantomData;
|
||||
let value: String = seed.deserialize(&mut *self.de)?;
|
||||
warn!("Struct::next_value_seed() => ignored Attribute value: {:?}", value);
|
||||
|
||||
let popped = self.de.node_stack.pop();
|
||||
debug!("<Struct as MapAccess>::next_value_seed() => popped: {:?}, node_stack: {:?}", popped, self.de.node_stack);
|
||||
}
|
||||
self.values_to_consume = 0;
|
||||
// First, if the key field is still present, emit the `__node_key` value
|
||||
if let Some(key) = self.key.take() {
|
||||
let de = key.into_deserializer();
|
||||
return seed.deserialize(de);
|
||||
}
|
||||
|
||||
let popped = self.de.node_stack.pop();
|
||||
debug!("<Struct as MapAccess>::next_value_seed() => popped: {:?}, node_stack: {:?}", popped, self.de.node_stack);
|
||||
// Then if there are attributes left, deserialize them first
|
||||
if let Some(attribute) = self.collection.attributes_mut().pop_front() {
|
||||
let de = NodeDefinitionDeserializer::new(attribute);
|
||||
return seed.deserialize(de);
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
// Else, deserialize the child nodes. Delegate popping nodes off the
|
||||
// children queue by the deserialize methods else handling `Struct`
|
||||
// sequences will break.
|
||||
let de = NodeCollectionDeserializer::new(&mut self.collection);
|
||||
seed.deserialize(de)
|
||||
}
|
||||
}
|
||||
|
||||
87
src/ip4.rs
87
src/ip4.rs
@@ -1,87 +0,0 @@
|
||||
use std::fmt;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
|
||||
use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
|
||||
|
||||
pub struct Ip4Addr(Ipv4Addr);
|
||||
|
||||
pub(crate) struct Ip4Visitor;
|
||||
|
||||
impl Ip4Addr {
|
||||
pub fn new(addr: Ipv4Addr) -> Self {
|
||||
Ip4Addr(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Ip4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Ip4Addr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Ip4Addr {
|
||||
type Target = Ipv4Addr;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Ip4Addr {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for Ip4Visitor {
|
||||
type Value = [u8; 4];
|
||||
|
||||
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("a sequence of 4 bytes with no size indicator")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where A: SeqAccess<'de>
|
||||
{
|
||||
trace!("Ip4Addr::visit_seq()");
|
||||
let v1: u8 = seq.next_element()?.unwrap();
|
||||
let v2: u8 = seq.next_element()?.unwrap();
|
||||
let v3: u8 = seq.next_element()?.unwrap();
|
||||
let v4: u8 = seq.next_element()?.unwrap();
|
||||
trace!("Ip4Addr:visit_seq() => [{}, {}, {}, {}]", v1, v2, v3, v4);
|
||||
Ok([v1, v2, v3, v4])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Ip4Addr {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
deserializer.deserialize_tuple_struct("ip4", 4, Ip4Visitor)
|
||||
.map(|v| {
|
||||
Ip4Addr(Ipv4Addr::from(v))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Ip4Addr {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
let octets = self.0.octets();
|
||||
let mut ts = serializer.serialize_tuple_struct("ip4", 4)?;
|
||||
ts.serialize_field(&octets[0])?;
|
||||
ts.serialize_field(&octets[1])?;
|
||||
ts.serialize_field(&octets[2])?;
|
||||
ts.serialize_field(&octets[3])?;
|
||||
ts.end()
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ mod byte_buffer;
|
||||
mod compression;
|
||||
mod encoding_type;
|
||||
mod error;
|
||||
mod ip4;
|
||||
mod node;
|
||||
mod node_types;
|
||||
mod options;
|
||||
@@ -50,7 +49,6 @@ pub use error::{KbinError, KbinErrorKind, Result};
|
||||
pub use node::{ExtraNodes, Node};
|
||||
pub use options::Options;
|
||||
pub use de::from_bytes;
|
||||
pub use ip4::Ip4Addr;
|
||||
pub use ser::to_bytes;
|
||||
pub use value::Value;
|
||||
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
use std::iter::Iterator;
|
||||
|
||||
use node::NodeDefinition;
|
||||
use error::{KbinError, KbinErrorKind};
|
||||
use node::{Node, NodeDefinition};
|
||||
use node_types::StandardType;
|
||||
use value::Value;
|
||||
|
||||
/// A collection of node definitions (`NodeDefinition`)
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct NodeCollection<'buf> {
|
||||
base: NodeDefinition<'buf>,
|
||||
attributes: Vec<NodeDefinition<'buf>>,
|
||||
children: Vec<NodeCollection<'buf>>,
|
||||
attributes: VecDeque<NodeDefinition<'buf>>,
|
||||
children: VecDeque<NodeCollection<'buf>>,
|
||||
}
|
||||
|
||||
impl<'buf> NodeCollection<'buf> {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(base: NodeDefinition<'buf>) -> Self {
|
||||
Self {
|
||||
base,
|
||||
attributes: VecDeque::with_capacity(0),
|
||||
children: VecDeque::with_capacity(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_iter<I>(mut iter: I) -> Option<NodeCollection<'buf>>
|
||||
where I: Iterator<Item = NodeDefinition<'buf>>
|
||||
{
|
||||
@@ -26,21 +36,20 @@ impl<'buf> NodeCollection<'buf> {
|
||||
NodeCollection::with_base(base, &mut iter)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn with_base<I>(base: NodeDefinition<'buf>, iter: &mut I) -> Option<NodeCollection<'buf>>
|
||||
where I: Iterator<Item = NodeDefinition<'buf>>
|
||||
{
|
||||
let mut attributes = Vec::new();
|
||||
let mut children = Vec::new();
|
||||
let mut attributes = VecDeque::new();
|
||||
let mut children = VecDeque::new();
|
||||
|
||||
loop {
|
||||
if let Some(def) = iter.next() {
|
||||
match def.node_type {
|
||||
StandardType::Attribute => attributes.push(def),
|
||||
StandardType::Attribute => attributes.push_back(def),
|
||||
StandardType::NodeEnd |
|
||||
StandardType::FileEnd => break,
|
||||
_ => match NodeCollection::with_base(def, iter) {
|
||||
Some(child) => children.push(child),
|
||||
Some(child) => children.push_back(child),
|
||||
None => return None,
|
||||
},
|
||||
}
|
||||
@@ -55,4 +64,89 @@ impl<'buf> NodeCollection<'buf> {
|
||||
children,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn base(&self) -> NodeDefinition<'buf> {
|
||||
self.base
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn attributes(&self) -> &VecDeque<NodeDefinition<'buf>> {
|
||||
&self.attributes
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn attributes_mut(&mut self) -> &mut VecDeque<NodeDefinition<'buf>> {
|
||||
&mut self.attributes
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children(&self) -> &VecDeque<NodeCollection<'buf>> {
|
||||
&self.children
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children_mut(&mut self) -> &mut VecDeque<NodeCollection<'buf>> {
|
||||
&mut self.children
|
||||
}
|
||||
|
||||
pub fn as_node(&self) -> Result<Node, KbinError> {
|
||||
let mut node = self.base.as_node()?;
|
||||
|
||||
for attr in &self.attributes {
|
||||
let key = attr.key()?.ok_or(KbinErrorKind::InvalidState)?;
|
||||
|
||||
if let Value::Attribute(value) = attr.value()? {
|
||||
node.set_attr(key, value);
|
||||
} else {
|
||||
return Err(KbinErrorKind::InvalidState.into());
|
||||
}
|
||||
}
|
||||
|
||||
for child in &self.children {
|
||||
node.append_child(child.as_node()?);
|
||||
}
|
||||
|
||||
Ok(node)
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayDebugWrapper<'a, T: fmt::Display + 'a>(&'a T, bool);
|
||||
impl<'a, T> fmt::Debug for DisplayDebugWrapper<'a, T>
|
||||
where T: fmt::Display
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.1 {
|
||||
write!(f, "{:#}", self.0)
|
||||
} else {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VecDisplayDebugWrapper<'a, T: fmt::Display + 'a>(&'a VecDeque<T>, bool);
|
||||
impl<'a, T> fmt::Debug for VecDisplayDebugWrapper<'a, T>
|
||||
where T: fmt::Display
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut l = f.debug_list();
|
||||
for entry in self.0 {
|
||||
l.entry(&DisplayDebugWrapper(&entry, self.1));
|
||||
}
|
||||
l.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> fmt::Display for NodeCollection<'buf> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut d = f.debug_struct("NodeCollection");
|
||||
|
||||
d.field("base", &DisplayDebugWrapper(&self.base, false));
|
||||
d.field("attributes", &VecDisplayDebugWrapper(&self.attributes, false));
|
||||
d.field("children", &VecDisplayDebugWrapper(&self.children, true));
|
||||
|
||||
d.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use std::fmt::{self, Write};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use serde::de::{self, Deserialize, DeserializeSeed, Error, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor};
|
||||
use serde::de::value::MapDeserializer;
|
||||
use serde::de::value::{MapDeserializer, SeqDeserializer};
|
||||
|
||||
use node::Node;
|
||||
use node_types::StandardType;
|
||||
@@ -27,12 +26,9 @@ impl<'de> NodeVisitor {
|
||||
|
||||
Ok(value)
|
||||
},
|
||||
// TODO: roll up `NodeStart` and everything else into a single map handler
|
||||
// Rolling up the `NodeStart` handling and other value types is not going
|
||||
// to happen as `NodeStart` nodes do not have a value
|
||||
node_type => {
|
||||
//let value = try!(map.next_value());
|
||||
//debug!("NodeVisitor::map_to_node(node_type: {:?}) => value: {:?}", node_type, value);
|
||||
|
||||
//let node = Node::with_value(key.to_owned(), value);
|
||||
let node = try!(map.next_value_seed(NodeWithValueSeed(key.to_owned())));
|
||||
debug!("NodeVisitor::map_to_node(node_type: {:?}) => node: {:?}", node_type, node);
|
||||
|
||||
@@ -55,9 +51,7 @@ impl<'de> Visitor<'de> for NodeVisitor {
|
||||
{
|
||||
trace!("NodeVisitor::visit_map()");
|
||||
|
||||
let mut attributes = None;
|
||||
let mut nodes = IndexMap::new();
|
||||
let mut value = None;
|
||||
let mut node = Node::new(self.key.unwrap_or_else(|| "".to_owned()));
|
||||
|
||||
while let Some(NodeStart { key, node_type }) = try!(map.next_key()) {
|
||||
debug!("NodeVisitor::visit_map() => node_type: {:?}, key: {:?}", node_type, key);
|
||||
@@ -68,7 +62,14 @@ impl<'de> Visitor<'de> for NodeVisitor {
|
||||
let node_value = try!(map.next_value());
|
||||
debug!("NodeVisitor::visit_map() => node value: {:?}", node_value);
|
||||
|
||||
value = Some(node_value);
|
||||
node.set_value(Some(node_value));
|
||||
} else if key == "__node_key" {
|
||||
trace!("NodeVisitor::visit_map() => got __node_key, getting node key");
|
||||
|
||||
let node_key: String = try!(map.next_value());
|
||||
debug!("NodeVisitor::visit_map() => node key: {:?}", node_key);
|
||||
|
||||
node.set_key(node_key);
|
||||
} else {
|
||||
match node_type {
|
||||
StandardType::Attribute => {
|
||||
@@ -76,47 +77,23 @@ impl<'de> Visitor<'de> for NodeVisitor {
|
||||
debug!("NodeVisitor::visit_map() => value: {:?}", value);
|
||||
|
||||
if let Value::Attribute(s) = try!(value) {
|
||||
let key = String::from(&key["attr_".len()..]);
|
||||
let attributes = attributes.get_or_insert_with(IndexMap::new);
|
||||
attributes.insert(key, s);
|
||||
//let key = String::from(&key["attr_".len()..]);
|
||||
node.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)?;
|
||||
let new_node = NodeVisitor::map_to_node(node_type, &key, &mut map)?;
|
||||
debug!("NodeVisitor::visit_map() => node: {:?}", node);
|
||||
|
||||
if !nodes.contains_key(&key) {
|
||||
nodes.insert(key, node);
|
||||
} else {
|
||||
let mut new_key = format!("{}1", key);
|
||||
let mut i = 2;
|
||||
while nodes.contains_key(&new_key) {
|
||||
new_key.truncate(key.len());
|
||||
write!(new_key, "{}", i);
|
||||
i += 1;
|
||||
}
|
||||
debug!("Node::visit_map() => next open key: {:?}", new_key);
|
||||
nodes.insert(new_key, node);
|
||||
}
|
||||
node.append_child(new_node);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let children = match nodes.len() {
|
||||
0 => None,
|
||||
_ => Some(nodes),
|
||||
};
|
||||
|
||||
//debug!("NodeVisitor::visit_map() => nodes: {:#?}", nodes);
|
||||
Ok(Node {
|
||||
key: self.key.unwrap_or_else(|| "".to_owned()),
|
||||
attributes,
|
||||
children,
|
||||
value,
|
||||
})
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -170,6 +147,8 @@ impl<'de> DeserializeSeed<'de> for NodeValueSeed {
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where D: de::Deserializer<'de>
|
||||
{
|
||||
trace!("NodeValueSeed(key: {:?})::deserialize()", self.0);
|
||||
|
||||
deserializer.deserialize_map(NodeVisitor { key: Some(self.0) })
|
||||
}
|
||||
}
|
||||
@@ -184,7 +163,7 @@ impl<'de> DeserializeSeed<'de> for NodeWithValueSeed {
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where D: de::Deserializer<'de>
|
||||
{
|
||||
trace!("NodeValue::deserialize()");
|
||||
trace!("NodeWithValueSeed(key: {:?})::deserialize()", self.0);
|
||||
|
||||
deserializer.deserialize_tuple_struct("__value", 0, NodeVisitor { key: Some(self.0) })
|
||||
}
|
||||
@@ -222,11 +201,11 @@ impl<'de, E: Error> SeqAccess<'de> for NodeDeserializer<E> {
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where T: DeserializeSeed<'de>
|
||||
{
|
||||
macro_rules! map_deserializer {
|
||||
($value:expr) => {
|
||||
macro_rules! make_deserializer {
|
||||
($value:expr, $deserializer:ident) => {
|
||||
match $value.take() {
|
||||
Some(value) => {
|
||||
let deserializer = MapDeserializer::new(value.into_iter());
|
||||
let deserializer = $deserializer::new(value.into_iter());
|
||||
seed.deserialize(deserializer).map(Some)
|
||||
},
|
||||
None => seed.deserialize(().into_deserializer()).map(Some),
|
||||
@@ -237,8 +216,8 @@ impl<'de, E: Error> SeqAccess<'de> for NodeDeserializer<E> {
|
||||
trace!("--> <NodeDeserializer as SeqAccess>::next_element_seed(index: {})", self.index);
|
||||
let value = match self.index {
|
||||
0 => seed.deserialize(self.node.key.as_str().into_deserializer()).map(Some),
|
||||
1 => map_deserializer!(self.node.attributes),
|
||||
2 => map_deserializer!(self.node.children),
|
||||
1 => make_deserializer!(self.node.attributes, MapDeserializer),
|
||||
2 => make_deserializer!(self.node.children, SeqDeserializer),
|
||||
3 => match self.node.value.take() {
|
||||
Some(value) => seed.deserialize(value.into_deserializer()).map(Some),
|
||||
None => seed.deserialize(().into_deserializer()).map(Some),
|
||||
@@ -286,7 +265,7 @@ impl<'de> Deserialize<'de> for NodeStart {
|
||||
type Value = NodeStart;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("valid node type (for NodeSeed)")
|
||||
formatter.write_str("enum input of a node (for NodeStart)")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::fmt;
|
||||
|
||||
use byte_buffer::strip_trailing_null_bytes;
|
||||
use encoding_type::EncodingType;
|
||||
use error::{KbinError, KbinErrorKind};
|
||||
@@ -6,7 +8,7 @@ use node_types::StandardType;
|
||||
use sixbit::{Sixbit, SixbitSize};
|
||||
use value::Value;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Key<'buf> {
|
||||
Compressed {
|
||||
size: SixbitSize,
|
||||
@@ -104,6 +106,13 @@ impl<'buf> NodeDefinition<'buf> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value_bytes(&self) -> Option<&'buf [u8]> {
|
||||
match self.data {
|
||||
NodeData::Some { ref value_data, .. } => Some(value_data),
|
||||
NodeData::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_node(&self) -> Result<Node, KbinError> {
|
||||
trace!("parsing definition: {:?}", self);
|
||||
match (self.node_type, self.data) {
|
||||
@@ -126,3 +135,54 @@ impl<'buf> NodeDefinition<'buf> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> fmt::Debug for Key<'buf> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Ok(key) = self.to_string() {
|
||||
write!(f, "\"{}\"", key)
|
||||
} else {
|
||||
match self {
|
||||
Key::Compressed { ref size, ref data } => {
|
||||
f.debug_struct("Compressed")
|
||||
.field("size", &size)
|
||||
.field("data", &data)
|
||||
.finish()
|
||||
},
|
||||
Key::Uncompressed { encoding, ref data } => {
|
||||
f.debug_struct("Uncompressed")
|
||||
.field("encoding", &encoding)
|
||||
.field("data", &data)
|
||||
.finish()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'buf> fmt::Display for NodeDefinition<'buf> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut d = f.debug_struct("NodeDefinition");
|
||||
d.field("node_type", &self.node_type);
|
||||
|
||||
match self.node_type {
|
||||
StandardType::Attribute |
|
||||
StandardType::String => {
|
||||
d.field("encoding", &self.encoding);
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
match self.data {
|
||||
NodeData::Some { ref key, ref value_data } => {
|
||||
match key.to_string() {
|
||||
Ok(key) => d.field("key", &key),
|
||||
Err(e) => d.field("key", &e),
|
||||
};
|
||||
d.field("value_data", &value_data);
|
||||
},
|
||||
NodeData::None => {},
|
||||
};
|
||||
|
||||
d.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,16 @@ impl<'de> Deserialize<'de> for ExtraNodes {
|
||||
while let Some(key) = try!(map.next_key::<String>()) {
|
||||
debug!("ExtraNodesVisitor::visit_map() => key: {:?}", key);
|
||||
|
||||
if key == "__node_key" {
|
||||
debug!("ExtraNodesVisitor::visit_map() => got __node_key, getting node key");
|
||||
|
||||
let node_key: String = try!(map.next_value());
|
||||
debug!("ExtraNodesVisitor::visit_map() => node key: {:?}", node_key);
|
||||
|
||||
extra.set_parent_key(node_key);
|
||||
continue;
|
||||
}
|
||||
|
||||
let marshal: Marshal = try!(map.next_value());
|
||||
debug!("ExtraNodesVisitor::visit_map() => marshal: {:?}", marshal);
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::mem;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use node::Node;
|
||||
@@ -9,6 +11,7 @@ mod ser;
|
||||
/// parent object
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct ExtraNodes {
|
||||
parent_key: String,
|
||||
attributes: IndexMap<String, String>,
|
||||
nodes: IndexMap<String, Node>,
|
||||
}
|
||||
@@ -16,11 +19,17 @@ pub struct ExtraNodes {
|
||||
impl ExtraNodes {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
parent_key: String::with_capacity(0),
|
||||
attributes: IndexMap::new(),
|
||||
nodes: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn parent_key(&self) -> &str {
|
||||
&self.parent_key
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn attributes(&self) -> &IndexMap<String, String> {
|
||||
&self.attributes
|
||||
@@ -31,6 +40,10 @@ impl ExtraNodes {
|
||||
&self.nodes
|
||||
}
|
||||
|
||||
pub fn set_parent_key(&mut self, key: String) -> String {
|
||||
mem::replace(&mut self.parent_key, key)
|
||||
}
|
||||
|
||||
pub fn set_attr(&mut self, key: String, value: String) -> Option<String> {
|
||||
self.attributes.insert(key, value)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
@@ -14,13 +15,21 @@ mod ser;
|
||||
pub use self::collection::NodeCollection;
|
||||
pub use self::definition::{Key, NodeData, NodeDefinition};
|
||||
pub use self::extra::ExtraNodes;
|
||||
pub use self::marshal::Marshal;
|
||||
pub use self::marshal::{Marshal, MarshalDeserializer};
|
||||
|
||||
/*
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Child {
|
||||
Single(Node),
|
||||
Multiple(Vec<Node>),
|
||||
}
|
||||
*/
|
||||
|
||||
#[derive(Clone, Default, PartialEq)]
|
||||
pub struct Node {
|
||||
key: String,
|
||||
attributes: Option<IndexMap<String, String>>,
|
||||
children: Option<IndexMap<String, Node>>,
|
||||
children: Option<Vec<Node>>,
|
||||
value: Option<Value>,
|
||||
}
|
||||
|
||||
@@ -73,7 +82,7 @@ impl Node {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children(&self) -> Option<&IndexMap<String, Node>> {
|
||||
pub fn children(&self) -> Option<&Vec<Node>> {
|
||||
self.children.as_ref()
|
||||
}
|
||||
|
||||
@@ -86,13 +95,50 @@ impl Node {
|
||||
(self.key, self.value)
|
||||
}
|
||||
|
||||
pub fn set_key(&mut self, key: String) {
|
||||
self.key = key;
|
||||
}
|
||||
|
||||
pub fn set_attr(&mut self, key: String, value: String) -> Option<String> {
|
||||
let attributes = self.attributes.get_or_insert_with(Default::default);
|
||||
attributes.insert(key, value)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, key: String, value: Node) -> Option<Node> {
|
||||
pub fn append_child(&mut self, value: Node) {
|
||||
let children = self.children.get_or_insert_with(Default::default);
|
||||
children.insert(key, value)
|
||||
children.push(value);
|
||||
|
||||
/*
|
||||
match children.entry(key) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
match entry.get_mut() {
|
||||
child @ Child::Single(_) => {
|
||||
let old = mem::replace(child, Child::Multiple(Vec::with_capacity(2)));
|
||||
let node = match old {
|
||||
Child::Single(node) => node,
|
||||
Child::Multiple(_) => panic!("`old` was `Child::Multiple` after checking"),
|
||||
};
|
||||
match child {
|
||||
Child::Multiple(ref mut nodes) => {
|
||||
nodes.push(node);
|
||||
nodes.push(value);
|
||||
},
|
||||
_ => panic!("Invalid result of node swap"),
|
||||
};
|
||||
},
|
||||
Child::Multiple(ref mut nodes) => {
|
||||
nodes.push(value);
|
||||
},
|
||||
};
|
||||
},
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(Child::Single(value));
|
||||
},
|
||||
};
|
||||
*/
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, value: Option<Value>) -> Option<Value> {
|
||||
mem::replace(&mut self.value, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use error::Result;
|
||||
//use node::NodeCollection;
|
||||
use node::NodeCollection;
|
||||
use node_types::StandardType;
|
||||
use reader::Reader;
|
||||
|
||||
@@ -45,20 +45,11 @@ impl Printer {
|
||||
};
|
||||
}
|
||||
|
||||
for def in &definitions {
|
||||
match def.node_type {
|
||||
StandardType::NodeEnd |
|
||||
StandardType::FileEnd => {},
|
||||
_ => {
|
||||
eprintln!("node: {:?}", def.as_node());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
let collection = NodeCollection::from_iter(definitions.into_iter());
|
||||
eprintln!("collection: {:#?}", collection);
|
||||
*/
|
||||
match collection {
|
||||
Some(collection) => eprintln!("collection: {:#}", collection),
|
||||
None => eprintln!("collection: {:?}", collection),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io::{Seek, SeekFrom};
|
||||
//use std::io::{Seek, SeekFrom};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use failure::ResultExt;
|
||||
@@ -21,9 +21,6 @@ pub struct Reader<'buf> {
|
||||
pub(crate) data_buf: ByteBufferRead<'buf>,
|
||||
|
||||
data_buf_start: u64,
|
||||
|
||||
last_node_type: Option<(StandardType, bool)>,
|
||||
last_node_identifier: Option<String>,
|
||||
}
|
||||
|
||||
impl<'buf> Reader<'buf> {
|
||||
@@ -68,9 +65,6 @@ impl<'buf> Reader<'buf> {
|
||||
data_buf,
|
||||
|
||||
data_buf_start: data_buf_start as u64,
|
||||
|
||||
last_node_type: None,
|
||||
last_node_identifier: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,16 +87,6 @@ impl<'buf> Reader<'buf> {
|
||||
self.encoding
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn last_node_type(&self) -> Option<(StandardType, bool)> {
|
||||
self.last_node_type
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn last_identifier(&self) -> Option<&str> {
|
||||
self.last_node_identifier.as_ref().map(String::as_str)
|
||||
}
|
||||
|
||||
pub fn check_if_node_buffer_end(&self) -> Result<()> {
|
||||
if self.node_buf.position() >= self.data_buf_start {
|
||||
Err(KbinErrorKind::EndOfNodeBuffer.into())
|
||||
@@ -111,6 +95,7 @@ impl<'buf> Reader<'buf> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn peek_node_type(&self) -> Result<(StandardType, bool)> {
|
||||
self.check_if_node_buffer_end()?;
|
||||
|
||||
@@ -142,17 +127,18 @@ impl<'buf> Reader<'buf> {
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn read_node_type(&mut self) -> Result<(StandardType, bool)> {
|
||||
self.check_if_node_buffer_end()?;
|
||||
|
||||
let raw_node_type = self.node_buf.read_u8().context(KbinErrorKind::NodeTypeRead)?;
|
||||
let value = Self::parse_node_type(raw_node_type)?;
|
||||
self.last_node_type = Some(value);
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn read_node_identifier(&mut self) -> Result<String> {
|
||||
let value = match self.compression {
|
||||
Compression::Compressed => {
|
||||
@@ -168,10 +154,9 @@ impl<'buf> Reader<'buf> {
|
||||
};
|
||||
debug!("Reader::read_node_identifier() => value: {:?}", value);
|
||||
|
||||
self.last_node_identifier = Some(value.clone());
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn read_node_data(&mut self, node_type: (StandardType, bool)) -> Result<&'buf [u8]> {
|
||||
let (node_type, is_array) = node_type;
|
||||
@@ -182,6 +167,10 @@ impl<'buf> Reader<'buf> {
|
||||
StandardType::String => self.data_buf.buf_read()?,
|
||||
StandardType::Binary => self.read_bytes()?,
|
||||
|
||||
StandardType::NodeStart |
|
||||
StandardType::NodeEnd |
|
||||
StandardType::FileEnd => &[],
|
||||
|
||||
_ if is_array => {
|
||||
let arr_size = self.read_u32().context(KbinErrorKind::ArrayLengthRead)?;
|
||||
let data = self.data_buf.get(arr_size)?;
|
||||
@@ -224,6 +213,7 @@ impl<'buf> Reader<'buf> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn read_string(&mut self) -> Result<String> {
|
||||
let value = self.data_buf.read_str(self.encoding)?;
|
||||
debug!("Reader::read_string() => value: {:?}", value);
|
||||
@@ -237,6 +227,7 @@ impl<'buf> Reader<'buf> {
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn read_u32(&mut self) -> Result<u32> {
|
||||
let value = self.data_buf.read_u32::<BigEndian>().context(KbinErrorKind::DataRead(4))?;
|
||||
|
||||
Reference in New Issue
Block a user