From f1f59fb3ae5721764442d072c482d17decc20bbd Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Sat, 18 Aug 2018 22:13:56 -0400 Subject: [PATCH] value: remove map support, add Node holder --- src/value/de.rs | 66 +++++++++++++----------------------------------- src/value/mod.rs | 25 ++++++++++-------- src/value/ser.rs | 4 +-- 3 files changed, 34 insertions(+), 61 deletions(-) diff --git a/src/value/de.rs b/src/value/de.rs index 7be7358..f8334fe 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -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(self, mut map: A) -> Result - where A: MapAccess<'de> - { - trace!("ValueVisitor::visit_map()"); - - let mut values: IndexMap = 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] diff --git a/src/value/mod.rs b/src/value/mod.rs index d293ec2..a45c7a6 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -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), - Map(IndexMap), + Array(StandardType, Vec), + Node(Box), } $( @@ -36,15 +36,15 @@ macro_rules! construct_types { )+ impl Value { - pub fn standard_type(&self) -> Option { + 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, diff --git a/src/value/ser.rs b/src/value/ser.rs index 7f194c6..e51319a 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -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), } }; }