mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-09 19:15:27 -05:00
value: add function to convert an array of values to bytes
This commit is contained in:
@@ -7,6 +7,13 @@ use node::{Node, NodeDefinition};
|
||||
use node_types::StandardType;
|
||||
use value::Value;
|
||||
|
||||
fn parse_index(s: &str) -> Option<usize> {
|
||||
if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) {
|
||||
return None;
|
||||
}
|
||||
s.parse().ok()
|
||||
}
|
||||
|
||||
/// A collection of node definitions (`NodeDefinition`)
|
||||
#[derive(Debug)]
|
||||
pub struct NodeCollection {
|
||||
@@ -109,6 +116,39 @@ impl NodeCollection {
|
||||
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
pub fn pointer<'a>(&'a self, pointer: &str) -> Option<&'a NodeCollection> {
|
||||
if pointer == "" {
|
||||
return Some(self);
|
||||
}
|
||||
if !pointer.starts_with('/') {
|
||||
return None;
|
||||
}
|
||||
let tokens = pointer
|
||||
.split('/')
|
||||
.skip(1)
|
||||
.map(|x| x.replace("~1", "/").replace("~0", "~"));
|
||||
let mut target = self;
|
||||
|
||||
for token in tokens {
|
||||
let target_opt = if let Some(index) = parse_index(&token) {
|
||||
eprintln!("index: {}", index);
|
||||
target.children().get(index)
|
||||
} else {
|
||||
eprintln!("token: {:?}", token);
|
||||
target.children().iter().find(|ref child| {
|
||||
child.base().key().ok().and_then(|x| x).expect("key not parseable") == token
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(t) = target_opt {
|
||||
target = t;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
Some(target)
|
||||
}
|
||||
}
|
||||
|
||||
struct DisplayDebugWrapper<'a, T: fmt::Display + 'a>(&'a T, bool);
|
||||
|
||||
104
src/node/mod.rs
104
src/node/mod.rs
@@ -17,6 +17,35 @@ pub use self::definition::{Key, NodeData, NodeDefinition};
|
||||
pub use self::extra::ExtraNodes;
|
||||
pub use self::marshal::{Marshal, MarshalDeserializer};
|
||||
|
||||
/*
|
||||
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));
|
||||
},
|
||||
};
|
||||
*/
|
||||
|
||||
#[derive(Clone, Default, PartialEq)]
|
||||
pub struct Node {
|
||||
key: String,
|
||||
@@ -78,11 +107,22 @@ impl Node {
|
||||
self.children.as_ref()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn children_mut(&mut self) -> Option<&mut Vec<Node>> {
|
||||
self.children.as_mut()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn value(&self) -> Option<&Value> {
|
||||
self.value.as_ref()
|
||||
}
|
||||
|
||||
pub fn attr(&self, key: &str) -> Option<&str> {
|
||||
self.attributes().and_then(|attributes| {
|
||||
attributes.get(key).map(String::as_str)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn into_key_and_value(self) -> (String, Option<Value>) {
|
||||
(self.key, self.value)
|
||||
}
|
||||
@@ -91,46 +131,48 @@ impl Node {
|
||||
self.key = key;
|
||||
}
|
||||
|
||||
pub fn set_attr(&mut self, key: String, value: String) -> Option<String> {
|
||||
pub fn set_attr<K, V>(&mut self, key: K, value: V) -> Option<String>
|
||||
where K: Into<String>,
|
||||
V: Into<String>
|
||||
{
|
||||
let attributes = self.attributes.get_or_insert_with(Default::default);
|
||||
attributes.insert(key, value)
|
||||
attributes.insert(key.into(), value.into())
|
||||
}
|
||||
|
||||
pub fn append_child(&mut self, value: Node) {
|
||||
let children = self.children.get_or_insert_with(Default::default);
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn get_first(&self, key: &str) -> Option<&Node> {
|
||||
if let Some(ref children) = self.children {
|
||||
for node in children {
|
||||
if node.key == key {
|
||||
return Some(node);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_first_mut(&mut self, key: &str) -> Option<&mut Node> {
|
||||
if let Some(ref mut children) = self.children {
|
||||
for node in children {
|
||||
if node.key == key {
|
||||
return Some(node);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,6 +440,11 @@ macro_rules! construct_types {
|
||||
self.to_bytes_inner(output)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn array_as_string(values: &[Value]) -> String {
|
||||
BorrowedValueArray(values).to_string()
|
||||
}
|
||||
|
||||
pub fn standard_type(&self) -> StandardType {
|
||||
match *self {
|
||||
$(
|
||||
@@ -564,6 +569,22 @@ impl fmt::Debug for Value {
|
||||
}
|
||||
}
|
||||
|
||||
/// A separate wrapper struct so `Value::Array` can be formatted by
|
||||
/// `<Value as fmt::Display>` and `Value::array_as_string`
|
||||
struct BorrowedValueArray<'a>(&'a [Value]);
|
||||
|
||||
impl<'a> fmt::Display for BorrowedValueArray<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, v) in self.0.iter().enumerate() {
|
||||
if i > 0 {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
fmt::Display::fmt(v, f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
macro_rules! display_value {
|
||||
@@ -612,15 +633,7 @@ impl fmt::Display for Value {
|
||||
true => f.write_str("1"),
|
||||
false => f.write_str("0"),
|
||||
},
|
||||
Value::Array(_, values) => {
|
||||
for (i, v) in values.iter().enumerate() {
|
||||
if i > 0 {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
fmt::Display::fmt(v, f)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Value::Array(_, values) => BorrowedValueArray(&values).fmt(f),
|
||||
Value::Node(_) => Ok(()),
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user