value: add function to convert an array of values to bytes

This commit is contained in:
Matt Bilker
2018-09-15 05:18:36 +00:00
parent dff69fe00e
commit 91b00a489c
3 changed files with 135 additions and 40 deletions

View File

@@ -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);

View File

@@ -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
}
}
}

View File

@@ -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(()),
}
};