node(collection): make a collection of NodeDefinition objects

This commit is contained in:
Matt Bilker
2018-09-05 17:20:57 +00:00
parent 16c7af157f
commit be6ef43aaa
5 changed files with 64 additions and 3 deletions

View File

@@ -29,7 +29,6 @@ mod error;
mod ip4;
mod kbin_wrapper;
mod node;
mod node_definition;
mod node_types;
mod options;
mod printer;

55
src/node/collection.rs Normal file
View File

@@ -0,0 +1,55 @@
use std::iter::Iterator;
use node::NodeDefinition;
use node_types::StandardType;
/// A collection of node definitions (`NodeDefinition`)
#[derive(Debug)]
pub struct NodeCollection<'buf> {
base: NodeDefinition<'buf>,
attributes: Vec<NodeDefinition<'buf>>,
children: Vec<NodeCollection<'buf>>,
}
impl<'buf> NodeCollection<'buf> {
pub fn from_iter<I>(mut iter: I) -> Option<NodeCollection<'buf>>
where I: Iterator<Item = NodeDefinition<'buf>>
{
let base = if let Some(def) = iter.next() {
def
} else {
return None;
};
NodeCollection::with_base(base, &mut iter)
}
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();
loop {
if let Some(def) = iter.next() {
match def.node_type {
StandardType::Attribute => attributes.push(def),
StandardType::NodeEnd |
StandardType::FileEnd => break,
_ => match NodeCollection::with_base(def, iter) {
Some(child) => children.push(child),
None => return None,
},
}
} else {
break;
}
}
Some(NodeCollection {
base,
attributes,
children,
})
}
}

View File

@@ -85,11 +85,14 @@ impl<'buf> NodeDefinition<'buf> {
pub fn into_node(self) -> Result<Node, KbinError> {
trace!("parsing definition: {:?}", self);
match (self.node_type, self.data) {
(StandardType::NodeStart, _) |
(StandardType::NodeEnd, _) |
(StandardType::FileEnd, _) => {
return Err(KbinErrorKind::InvalidNodeType(self.node_type).into());
},
(StandardType::NodeStart, NodeData::Some { key, .. }) => {
let key = key.to_string()?;
Ok(Node::new(key))
},
(StandardType::Attribute, NodeData::Some { key, value_data }) => {
let key = key.to_string()?;
let data = strip_trailing_null_bytes(value_data);

View File

@@ -4,11 +4,15 @@ use indexmap::IndexMap;
use value::Value;
mod collection;
pub(crate) mod de;
mod definition;
mod extra;
mod marshal;
mod ser;
pub use self::collection::NodeCollection;
pub use self::definition::{Key, NodeData, NodeDefinition};
pub use self::extra::ExtraNodes;
pub use self::marshal::Marshal;

View File

@@ -7,7 +7,7 @@ use byte_buffer::ByteBufferRead;
use compression::Compression;
use encoding_type::EncodingType;
use error::{KbinErrorKind, Result};
use node_definition::{Key, NodeData, NodeDefinition};
use node::{Key, NodeData, NodeDefinition};
use node_types::StandardType;
use sixbit::Sixbit;