From 78f7a9b93a34f67d8df2db3ff5bfa26357edfa17 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 2 Feb 2022 01:30:10 +0000 Subject: [PATCH] node: make attributes and children non-null --- kbinxml/src/node/mod.rs | 185 ++++++++++---------------------- kbinxml/src/to_text_xml/node.rs | 25 ++--- kbinxml/src/writer.rs | 66 ++++++------ 3 files changed, 96 insertions(+), 180 deletions(-) diff --git a/kbinxml/src/node/mod.rs b/kbinxml/src/node/mod.rs index a7d68be..87fee15 100644 --- a/kbinxml/src/node/mod.rs +++ b/kbinxml/src/node/mod.rs @@ -1,5 +1,4 @@ use std::fmt; -use std::iter::IntoIterator; use std::mem; use indexmap::IndexMap; @@ -27,29 +26,22 @@ fn parse_index(s: &str) -> Option { s.parse().ok() } -pub struct OptionIterator { - inner: Option, -} - #[derive(Clone, Default, PartialEq)] pub struct Node { key: String, - attributes: Option>, - children: Option>, + attributes: IndexMap, + children: Vec, value: Option, } impl fmt::Debug for Node { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut d = f.debug_struct("Node"); - d.field("key", &self.key); - if let Some(ref attributes) = self.attributes { - d.field("attributes", attributes); - } - if let Some(ref children) = self.children { - d.field("children", children); - } + d.field("key", &self.key); + d.field("attributes", &self.attributes); + d.field("children", &self.children); + if let Some(ref value) = self.value { d.field("value", value); } @@ -65,8 +57,8 @@ impl Node { { Self { key: key.into(), - attributes: None, - children: None, + attributes: IndexMap::new(), + children: Vec::new(), value: None, } } @@ -77,8 +69,8 @@ impl Node { { Self { key: key.into(), - attributes: Some(convert_attributes(attrs)), - children: None, + attributes: convert_attributes(attrs), + children: Vec::new(), value: None, } } @@ -89,8 +81,8 @@ impl Node { { Self { key: key.into(), - attributes: None, - children: None, + attributes: IndexMap::new(), + children: Vec::new(), value: Some(value), } } @@ -102,8 +94,8 @@ impl Node { { Self { key: key.into(), - attributes: None, - children: Some(nodes.into()), + attributes: IndexMap::new(), + children: nodes.into(), value: None, } } @@ -115,8 +107,8 @@ impl Node { { Self { key: key.into(), - attributes: Some(convert_attributes(attrs)), - children: Some(nodes.into()), + attributes: convert_attributes(attrs), + children: nodes.into(), value: None, } } @@ -127,8 +119,8 @@ impl Node { { Self { key: key.into(), - attributes: Some(convert_attributes(attrs)), - children: None, + attributes: convert_attributes(attrs), + children: Vec::new(), value: Some(value), } } @@ -139,23 +131,23 @@ impl Node { } #[inline] - pub fn attributes(&self) -> Option<&IndexMap> { - self.attributes.as_ref() + pub fn attributes(&self) -> &IndexMap { + &self.attributes } #[inline] - pub fn attributes_mut(&mut self) -> Option<&mut IndexMap> { - self.attributes.as_mut() + pub fn attributes_mut(&mut self) -> &mut IndexMap { + &mut self.attributes } #[inline] - pub fn children(&self) -> Option<&Vec> { - self.children.as_ref() + pub fn children(&self) -> &[Node] { + &self.children } #[inline] - pub fn children_mut(&mut self) -> Option<&mut Vec> { - self.children.as_mut() + pub fn children_mut(&mut self) -> &mut Vec { + &mut self.children } #[inline] @@ -168,32 +160,20 @@ impl Node { self.value.as_mut() } - #[inline] - pub fn children_iter(&self) -> OptionIterator<&Vec> { - OptionIterator::new(self.children()) - } - - #[inline] - pub fn children_iter_mut(&mut self) -> OptionIterator<&mut Vec> { - OptionIterator::new(self.children_mut()) - } - pub fn attr(&self, key: &str) -> Option<&str> { - self.attributes() - .and_then(|attributes| attributes.get(key).map(String::as_str)) + self.attributes.get(key).map(String::as_str) } pub fn attr_mut(&mut self, key: &str) -> Option<&mut String> { - self.attributes_mut() - .and_then(|attributes| attributes.get_mut(key)) + self.attributes.get_mut(key) } pub fn into_key_and_value(self) -> (String, Option) { (self.key, self.value) } - pub fn set_key(&mut self, key: String) { - self.key = key; + pub fn set_key>(&mut self, key: K) { + self.key = key.into(); } pub fn set_attr(&mut self, key: K, value: V) -> Option @@ -201,25 +181,19 @@ impl Node { K: Into, V: Into, { - let attributes = self.attributes.get_or_insert_with(Default::default); - attributes.insert(key.into(), value.into()) + self.attributes.insert(key.into(), value.into()) } pub fn remove_attr(&mut self, key: &str) -> Option { - self.attributes - .as_mut() - .and_then(|attributes| attributes.swap_remove(key)) + self.attributes.swap_remove(key) } pub fn sort_attrs(&mut self) { - if let Some(ref mut attributes) = self.attributes { - attributes.sort_keys(); - } + self.attributes.sort_keys(); } pub fn append_child(&mut self, value: Node) { - let children = self.children.get_or_insert_with(Default::default); - children.push(value); + self.children.push(value); } pub fn set_value(&mut self, value: Option) -> Option { @@ -227,11 +201,9 @@ impl Node { } pub fn has(&self, key: &str) -> bool { - if let Some(ref children) = self.children { - for node in children { - if node.key == key { - return true; - } + for node in self.children.iter() { + if node.key == key { + return true; } } @@ -239,11 +211,9 @@ impl Node { } pub fn get_child(&self, key: &str) -> Option<&Node> { - if let Some(ref children) = self.children { - for node in children { - if node.key == key { - return Some(node); - } + for node in self.children.iter() { + if node.key == key { + return Some(node); } } @@ -251,11 +221,9 @@ impl Node { } pub fn get_child_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); - } + for node in self.children.iter_mut() { + if node.key == key { + return Some(node); } } @@ -263,27 +231,15 @@ impl Node { } pub fn remove_child(&mut self, key: &str) -> Option { - if let Some(ref mut children) = self.children { - let index = children - .iter() - .enumerate() - .find(|(_, child)| child.key() == key) - .map(|(index, _)| index); + let index = self.children.iter().position(|child| child.key() == key); - if let Some(index) = index { - return Some(children.remove(index)); - } + if let Some(index) = index { + return Some(self.children.remove(index)); } None } - pub fn remove_child_at(&mut self, index: usize) -> Option { - self.children - .as_mut() - .map(|children| children.remove(index)) - } - pub fn pointer<'a>(&'a self, pointer: &[&str]) -> Option<&'a Node> { if pointer.is_empty() { return Some(self); @@ -291,15 +247,13 @@ impl Node { let mut target = self; for token in pointer { - let children = match target.children { - Some(ref v) => v, - None => return None, - }; - let target_opt = if let Some(index) = parse_index(token) { - children.get(index) + target.children.get(index) } else { - children.iter().find(|ref child| child.key() == *token) + target + .children + .iter() + .find(|ref child| child.key() == *token) }; if let Some(t) = target_opt { @@ -318,15 +272,13 @@ impl Node { let mut target = self; for token in pointer { - let children = match target.children { - Some(ref mut v) => v, - None => return None, - }; - let target_opt = if let Some(index) = parse_index(token) { - children.get_mut(index) + target.children.get_mut(index) } else { - children.iter_mut().find(|ref child| child.key() == *token) + target + .children + .iter_mut() + .find(|ref child| child.key() == *token) }; if let Some(t) = target_opt { @@ -338,28 +290,3 @@ impl Node { Some(target) } } - -impl OptionIterator -where - T: IntoIterator, -{ - pub fn new(inner: Option) -> Self { - OptionIterator { - inner: inner.map(|inner| inner.into_iter()), - } - } -} - -impl Iterator for OptionIterator -where - T: IntoIterator, -{ - type Item = T::Item; - - fn next(&mut self) -> Option { - match self.inner { - Some(ref mut inner) => inner.next(), - None => None, - } - } -} diff --git a/kbinxml/src/to_text_xml/node.rs b/kbinxml/src/to_text_xml/node.rs index 5c6042c..4122ba1 100644 --- a/kbinxml/src/to_text_xml/node.rs +++ b/kbinxml/src/to_text_xml/node.rs @@ -51,15 +51,13 @@ impl ToTextXml for Node { } } - if let Some(attributes) = self.attributes() { - for (key, value) in attributes { - let value = BytesText::from_plain_str(&value); + for (key, value) in self.attributes() { + let value = BytesText::from_plain_str(&value); - elem.push_attribute(Attribute { - key: key.as_bytes(), - value: Cow::Borrowed(value.escaped()), - }); - } + elem.push_attribute(Attribute { + key: key.as_bytes(), + value: Cow::Borrowed(value.escaped()), + }); } // Now write the value contents. @@ -76,10 +74,7 @@ impl ToTextXml for Node { }; let has_value = start_elem.is_none(); - let has_children = match self.children() { - Some(children) => !children.is_empty(), - None => false, - }; + let has_children = !self.children().is_empty(); // A `Some` value here means the start element was not written if let Some(start_elem) = start_elem { @@ -90,10 +85,8 @@ impl ToTextXml for Node { } } - if let Some(children) = self.children() { - for child in children { - child.write(writer)?; - } + for child in self.children() { + child.write(writer)?; } if has_value || has_children { diff --git a/kbinxml/src/writer.rs b/kbinxml/src/writer.rs index b9d3db8..9f005e8 100644 --- a/kbinxml/src/writer.rs +++ b/kbinxml/src/writer.rs @@ -351,46 +351,42 @@ impl Writeable for Node { write_value(options, data_buf, node_type, is_array, value)?; } - if let Some(attributes) = self.attributes() { - for (key, value) in attributes { - trace!("Node write_node => attr: {}, value: {}", key, value); + for (key, value) in self.attributes() { + trace!("Node write_node => attr: {}, value: {}", key, value); - data_buf - .write_str(options.encoding, value) - .context(DataBuffer { node_type })?; + data_buf + .write_str(options.encoding, value) + .context(DataBuffer { node_type })?; - node_buf - .write_u8(StandardType::Attribute as u8) - .context(DataWrite { - node_type: StandardType::Attribute, - })?; + node_buf + .write_u8(StandardType::Attribute as u8) + .context(DataWrite { + node_type: StandardType::Attribute, + })?; - match options.compression { - CompressionType::Compressed => { - Sixbit::pack(&mut **node_buf, &key).context(NodeSixbitName)? - }, - CompressionType::Uncompressed => { - let data = options.encoding.encode_bytes(&key).context( - NodeUncompressedNameEncode { - encoding: options.encoding, - }, - )?; - let len = (data.len() - 1) as u8; - node_buf - .write_u8(len | ARRAY_MASK) - .context(NodeUncompressedNameLength)?; - node_buf - .write_all(&data) - .context(NodeUncompressedNameData)?; - }, - }; - } + match options.compression { + CompressionType::Compressed => { + Sixbit::pack(&mut **node_buf, &key).context(NodeSixbitName)? + }, + CompressionType::Uncompressed => { + let data = options.encoding.encode_bytes(&key).context( + NodeUncompressedNameEncode { + encoding: options.encoding, + }, + )?; + let len = (data.len() - 1) as u8; + node_buf + .write_u8(len | ARRAY_MASK) + .context(NodeUncompressedNameLength)?; + node_buf + .write_all(&data) + .context(NodeUncompressedNameData)?; + }, + }; } - if let Some(children) = self.children() { - for child in children { - child.write_node(options, node_buf, data_buf)?; - } + for child in self.children() { + child.write_node(options, node_buf, data_buf)?; } // node end always has the array bit set