mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-08 10:35:32 -05:00
value: remove map support, add Node holder
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user