value: remove map support, add Node holder

This commit is contained in:
Matt Bilker
2018-08-18 22:13:56 -04:00
parent 878194e1fb
commit f1f59fb3ae
3 changed files with 34 additions and 61 deletions

View File

@@ -1,7 +1,6 @@
use std::fmt;
use indexmap::IndexMap;
use serde::de::{self, Deserialize, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
use serde::de::{self, Deserialize, EnumAccess, Error, SeqAccess, VariantAccess, Visitor};
use node_types::StandardType;
use value::Value;
@@ -71,58 +70,27 @@ impl<'de> Deserialize<'de> for Value {
trace!("ValueVisitor::visit_seq()");
let mut vec = Vec::new();
let mut array_node_type = None;
while let Some(elem) = try!(seq.next_element()) {
debug!("ValueVisitor::visit_seq() => elem: {:?}", elem);
let elem: Value = elem;
let node_type = elem.standard_type();
// Ensure that all elements in the `Vec` are of the same `Value` variant
if let Some(array_node_type) = array_node_type {
if array_node_type != node_type {
return Err(A::Error::custom("All values in `Value::Array` must be the same node type"));
}
} else {
array_node_type = Some(node_type);
}
debug!("ValueVisitor::visit_seq() => node_type: {:?}, elem: {:?}", node_type, elem);
vec.push(elem);
}
Ok(Value::Array(vec))
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where A: MapAccess<'de>
{
trace!("ValueVisitor::visit_map()");
let mut values: IndexMap<String, Value> = IndexMap::new();
while let Some((key, value)) = try!(map.next_entry()) {
// Check to see if this is an attribute
let key: String = key;
let (key, value) = if key.starts_with("attr_") {
let value = match value {
Value::Attribute(_) => value,
_ => return Err(A::Error::custom("Key that starts with 'attr_' must be an `Attribute`")),
};
(&key["attr_".len()..], value)
} else {
(key.as_str(), value)
};
debug!("ValueVisitor::visit_map() => key: {:?}, value: {:?}", key, value);
if values.contains_key(key) {
let replace = match values.get_mut(key).expect("Key must exist from `contains_key`") {
Value::Array(ref mut arr) => {
arr.push(value);
false
},
// Replace the `Value` with an array of `Value`s
_ => true,
};
if replace {
let entry = values.remove(key).expect("Key must exist from `contains_key`");
values.insert(key.to_owned(), Value::Array(vec![entry]));
}
} else {
values.insert(key.to_owned(), value);
}
}
Ok(Value::Map(values))
let array_node_type = array_node_type.ok_or_else(|| A::Error::custom("`Value::Array` must have node type"))?;
Ok(Value::Array(array_node_type, vec))
}
#[inline]

View File

@@ -1,9 +1,9 @@
use std::fmt;
use std::net::Ipv4Addr;
use indexmap::IndexMap;
use serde::de::{Deserialize, Deserializer, DeserializeSeed};
use node::Node;
use node_types::StandardType;
mod de;
@@ -23,8 +23,8 @@ macro_rules! construct_types {
Time(u32),
Attribute(String),
Array(Vec<Value>),
Map(IndexMap<String, Value>),
Array(StandardType, Vec<Value>),
Node(Box<Node>),
}
$(
@@ -36,15 +36,15 @@ macro_rules! construct_types {
)+
impl Value {
pub fn standard_type(&self) -> Option<StandardType> {
pub fn standard_type(&self) -> StandardType {
match *self {
$(
Value::$konst(_) => Some(StandardType::$konst),
Value::$konst(_) => StandardType::$konst,
)+
Value::Time(_) => Some(StandardType::Time),
Value::Attribute(_) => Some(StandardType::Attribute),
Value::Array(_) => None,
Value::Map(_) => Some(StandardType::NodeStart),
Value::Time(_) => StandardType::Time,
Value::Attribute(_) => StandardType::Attribute,
Value::Array(node_type, _) => node_type,
Value::Node(_) => StandardType::NodeStart,
}
}
}
@@ -95,6 +95,11 @@ impl fmt::Debug for Value {
Value::$konst_debug(ref v) => write!(f, concat!(stringify!($konst_debug), "({:?})"), v),
)*
Value::Binary(ref v) => write!(f, "Binary(0x{:02x?})", v),
Value::Array(ref node_type, ref a) => if f.alternate() {
write!(f, "Array({:?}, {:#?}", node_type, a)
} else {
write!(f, "Array({:?}, {:?}", node_type, a)
},
}
};
}
@@ -106,7 +111,7 @@ impl fmt::Debug for Value {
Float, Double, Boolean
],
debug_alternate: [
Map, Array
Node
],
debug: [
String, Time, Ip4,

View File

@@ -41,8 +41,8 @@ impl Serialize for Value {
},
Value::Attribute(ref s) => serializer.serialize_str(&format!("attr_{}", s)),
Value::Array(ref a) => a.serialize(serializer),
Value::Map(ref m) => m.serialize(serializer),
Value::Array(_, ref a) => a.serialize(serializer),
Value::Node(ref n) => n.serialize(serializer),
}
};
}