Rustfmt pass, and rustfmt --check in CI"
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
e1b53eae3c
commit
a104ebc3f6
79 changed files with 1344 additions and 957 deletions
|
|
@ -13,7 +13,7 @@ macro_rules! impl_into_attribute_value {
|
|||
Some(format!("{}", self))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_into_attribute_values {
|
||||
|
|
@ -22,7 +22,19 @@ macro_rules! impl_into_attribute_values {
|
|||
}
|
||||
}
|
||||
|
||||
impl_into_attribute_values!(usize, u64, u32, u16, u8, isize, i64, i32, i16, i8, ::std::net::IpAddr);
|
||||
impl_into_attribute_values!(
|
||||
usize,
|
||||
u64,
|
||||
u32,
|
||||
u16,
|
||||
u8,
|
||||
isize,
|
||||
i64,
|
||||
i32,
|
||||
i16,
|
||||
i8,
|
||||
::std::net::IpAddr
|
||||
);
|
||||
|
||||
impl IntoAttributeValue for String {
|
||||
fn into_attribute_value(self) -> Option<String> {
|
||||
|
|
@ -56,14 +68,20 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_into_attribute_value_on_ints() {
|
||||
assert_eq!(16u8.into_attribute_value().unwrap() , "16");
|
||||
assert_eq!(17u16.into_attribute_value().unwrap() , "17");
|
||||
assert_eq!(18u32.into_attribute_value().unwrap() , "18");
|
||||
assert_eq!(19u64.into_attribute_value().unwrap() , "19");
|
||||
assert_eq!( 16i8.into_attribute_value().unwrap() , "16");
|
||||
assert_eq!(16u8.into_attribute_value().unwrap(), "16");
|
||||
assert_eq!(17u16.into_attribute_value().unwrap(), "17");
|
||||
assert_eq!(18u32.into_attribute_value().unwrap(), "18");
|
||||
assert_eq!(19u64.into_attribute_value().unwrap(), "19");
|
||||
assert_eq!(16i8.into_attribute_value().unwrap(), "16");
|
||||
assert_eq!((-17i16).into_attribute_value().unwrap(), "-17");
|
||||
assert_eq!( 18i32.into_attribute_value().unwrap(), "18");
|
||||
assert_eq!(18i32.into_attribute_value().unwrap(), "18");
|
||||
assert_eq!((-19i64).into_attribute_value().unwrap(), "-19");
|
||||
assert_eq!(IpAddr::from_str("127.000.0.1").unwrap().into_attribute_value().unwrap(), "127.0.0.1");
|
||||
assert_eq!(
|
||||
IpAddr::from_str("127.000.0.1")
|
||||
.unwrap()
|
||||
.into_attribute_value()
|
||||
.unwrap(),
|
||||
"127.0.0.1"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ use crate::error::{Error, Result};
|
|||
use crate::namespace_set::NamespaceSet;
|
||||
use crate::node::Node;
|
||||
|
||||
use std::io:: Write;
|
||||
use std::collections::{btree_map, BTreeMap};
|
||||
use std::io::Write;
|
||||
|
||||
use std::str;
|
||||
use std::rc::Rc;
|
||||
use std::borrow::Cow;
|
||||
use std::rc::Rc;
|
||||
use std::str;
|
||||
|
||||
use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, Event};
|
||||
use quick_xml::Reader as EventReader;
|
||||
use quick_xml::Writer as EventWriter;
|
||||
use quick_xml::events::{Event, BytesStart, BytesEnd, BytesDecl};
|
||||
|
||||
use std::io::BufRead;
|
||||
|
||||
|
|
@ -68,7 +68,6 @@ pub fn escape(raw: &[u8]) -> Cow<[u8]> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
/// A struct representing a DOM Element.
|
||||
pub struct Element {
|
||||
|
|
@ -97,9 +96,16 @@ impl FromStr for Element {
|
|||
}
|
||||
|
||||
impl Element {
|
||||
fn new<NS: Into<NamespaceSet>>(name: String, prefix: Option<String>, namespaces: NS, attributes: BTreeMap<String, String>, children: Vec<Node>) -> Element {
|
||||
fn new<NS: Into<NamespaceSet>>(
|
||||
name: String,
|
||||
prefix: Option<String>,
|
||||
namespaces: NS,
|
||||
attributes: BTreeMap<String, String>,
|
||||
children: Vec<Node>,
|
||||
) -> Element {
|
||||
Element {
|
||||
prefix, name,
|
||||
prefix,
|
||||
name,
|
||||
namespaces: Rc::new(namespaces.into()),
|
||||
attributes,
|
||||
children,
|
||||
|
|
@ -186,7 +192,7 @@ impl Element {
|
|||
/// Returns a reference to the value of the given attribute, if it exists, else `None`.
|
||||
pub fn attr(&self, name: &str) -> Option<&str> {
|
||||
if let Some(value) = self.attributes.get(name) {
|
||||
return Some(value)
|
||||
return Some(value);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
@ -225,7 +231,8 @@ impl Element {
|
|||
let val = val.into_attribute_value();
|
||||
|
||||
if let Some(value) = self.attributes.get_mut(&name) {
|
||||
*value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
|
||||
*value = val
|
||||
.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -249,8 +256,7 @@ impl Element {
|
|||
/// assert_eq!(elem.is("wrong", "wrong"), false);
|
||||
/// ```
|
||||
pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
|
||||
self.name == name.as_ref() &&
|
||||
self.has_ns(namespace)
|
||||
self.name == name.as_ref() && self.has_ns(namespace)
|
||||
}
|
||||
|
||||
/// Returns whether the element has the given namespace.
|
||||
|
|
@ -278,22 +284,22 @@ impl Element {
|
|||
match e {
|
||||
Event::Empty(ref e) | Event::Start(ref e) => {
|
||||
break build_element(reader, e)?;
|
||||
},
|
||||
}
|
||||
Event::Eof => {
|
||||
return Err(Error::EndOfDocument);
|
||||
},
|
||||
}
|
||||
#[cfg(not(feature = "comments"))]
|
||||
Event::Comment { .. } => {
|
||||
return Err(Error::CommentsDisabled);
|
||||
}
|
||||
#[cfg(feature = "comments")]
|
||||
Event::Comment { .. } => (),
|
||||
Event::Text { .. } |
|
||||
Event::End { .. } |
|
||||
Event::CData { .. } |
|
||||
Event::Decl { .. } |
|
||||
Event::PI { .. } |
|
||||
Event::DocType { .. } => (), // TODO: may need more errors
|
||||
Event::Text { .. }
|
||||
| Event::End { .. }
|
||||
| Event::CData { .. }
|
||||
| Event::Decl { .. }
|
||||
| Event::PI { .. }
|
||||
| Event::DocType { .. } => (), // TODO: may need more errors
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -305,11 +311,11 @@ impl Element {
|
|||
let elem = build_element(reader, e)?;
|
||||
// Since there is no Event::End after, directly append it to the current node
|
||||
stack.last_mut().unwrap().append_child(elem);
|
||||
},
|
||||
}
|
||||
Event::Start(ref e) => {
|
||||
let elem = build_element(reader, e)?;
|
||||
stack.push(elem);
|
||||
},
|
||||
}
|
||||
Event::End(ref e) => {
|
||||
if stack.len() <= 1 {
|
||||
break;
|
||||
|
|
@ -327,15 +333,15 @@ impl Element {
|
|||
if possible_prefix != prefix.as_bytes() {
|
||||
return Err(Error::InvalidElementClosed);
|
||||
}
|
||||
},
|
||||
}
|
||||
None => {
|
||||
return Err(Error::InvalidElementClosed);
|
||||
},
|
||||
}
|
||||
}
|
||||
if name != elem.name().as_bytes() {
|
||||
return Err(Error::InvalidElementClosed);
|
||||
}
|
||||
},
|
||||
}
|
||||
None => {
|
||||
if elem.prefix().is_some() {
|
||||
return Err(Error::InvalidElementClosed);
|
||||
|
|
@ -343,28 +349,28 @@ impl Element {
|
|||
if possible_prefix != elem.name().as_bytes() {
|
||||
return Err(Error::InvalidElementClosed);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
to.append_child(elem);
|
||||
}
|
||||
},
|
||||
}
|
||||
Event::Text(s) => {
|
||||
let text = s.unescape_and_decode(reader)?;
|
||||
if text != "" {
|
||||
let current_elem = stack.last_mut().unwrap();
|
||||
current_elem.append_text_node(text);
|
||||
}
|
||||
},
|
||||
}
|
||||
Event::CData(s) => {
|
||||
let text = reader.decode(&s)?.to_owned();
|
||||
if text != "" {
|
||||
let current_elem = stack.last_mut().unwrap();
|
||||
current_elem.append_text_node(text);
|
||||
}
|
||||
},
|
||||
}
|
||||
Event::Eof => {
|
||||
break;
|
||||
},
|
||||
}
|
||||
#[cfg(not(feature = "comments"))]
|
||||
Event::Comment(_) => return Err(Error::CommentsDisabled),
|
||||
#[cfg(feature = "comments")]
|
||||
|
|
@ -374,10 +380,8 @@ impl Element {
|
|||
let current_elem = stack.last_mut().unwrap();
|
||||
current_elem.append_comment_node(comment);
|
||||
}
|
||||
},
|
||||
Event::Decl { .. } |
|
||||
Event::PI { .. } |
|
||||
Event::DocType { .. } => (),
|
||||
}
|
||||
Event::Decl { .. } | Event::PI { .. } | Event::DocType { .. } => (),
|
||||
}
|
||||
}
|
||||
Ok(stack.pop().unwrap())
|
||||
|
|
@ -408,7 +412,7 @@ impl Element {
|
|||
Some(ref prefix) => {
|
||||
let key = format!("xmlns:{}", prefix);
|
||||
start.push_attribute((key.as_bytes(), ns.as_bytes()))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
for (key, value) in &self.attributes {
|
||||
|
|
@ -417,7 +421,7 @@ impl Element {
|
|||
|
||||
if self.children.is_empty() {
|
||||
writer.write_event(Event::Empty(start))?;
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
writer.write_event(Event::Start(start))?;
|
||||
|
|
@ -448,12 +452,14 @@ impl Element {
|
|||
/// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[inline] pub fn nodes(&self) -> Nodes {
|
||||
#[inline]
|
||||
pub fn nodes(&self) -> Nodes {
|
||||
self.children.iter()
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable references to every child node of this element.
|
||||
#[inline] pub fn nodes_mut(&mut self) -> NodesMut {
|
||||
#[inline]
|
||||
pub fn nodes_mut(&mut self) -> NodesMut {
|
||||
self.children.iter_mut()
|
||||
}
|
||||
|
||||
|
|
@ -472,14 +478,16 @@ impl Element {
|
|||
/// assert_eq!(iter.next().unwrap().name(), "child3");
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[inline] pub fn children(&self) -> Children {
|
||||
#[inline]
|
||||
pub fn children(&self) -> Children {
|
||||
Children {
|
||||
iter: self.children.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable references to every child element of this element.
|
||||
#[inline] pub fn children_mut(&mut self) -> ChildrenMut {
|
||||
#[inline]
|
||||
pub fn children_mut(&mut self) -> ChildrenMut {
|
||||
ChildrenMut {
|
||||
iter: self.children.iter_mut(),
|
||||
}
|
||||
|
|
@ -499,14 +507,16 @@ impl Element {
|
|||
/// assert_eq!(iter.next().unwrap(), " world!");
|
||||
/// assert_eq!(iter.next(), None);
|
||||
/// ```
|
||||
#[inline] pub fn texts(&self) -> Texts {
|
||||
#[inline]
|
||||
pub fn texts(&self) -> Texts {
|
||||
Texts {
|
||||
iter: self.children.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over mutable references to every text node of this element.
|
||||
#[inline] pub fn texts_mut(&mut self) -> TextsMut {
|
||||
#[inline]
|
||||
pub fn texts_mut(&mut self) -> TextsMut {
|
||||
TextsMut {
|
||||
iter: self.children.iter_mut(),
|
||||
}
|
||||
|
|
@ -630,7 +640,11 @@ impl Element {
|
|||
/// assert_eq!(elem.get_child("b", "other_ns"), None);
|
||||
/// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
|
||||
/// ```
|
||||
pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
|
||||
pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(
|
||||
&self,
|
||||
name: N,
|
||||
namespace: NS,
|
||||
) -> Option<&Element> {
|
||||
for fork in &self.children {
|
||||
if let Node::Element(ref e) = *fork {
|
||||
if e.is(name.as_ref(), namespace.as_ref()) {
|
||||
|
|
@ -643,7 +657,11 @@ impl Element {
|
|||
|
||||
/// Returns a mutable reference to the first child element with the specific name and namespace,
|
||||
/// if it exists in the direct descendants of this `Element`, else returns `None`.
|
||||
pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
|
||||
pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(
|
||||
&mut self,
|
||||
name: N,
|
||||
namespace: NS,
|
||||
) -> Option<&mut Element> {
|
||||
for fork in &mut self.children {
|
||||
if let Node::Element(ref mut e) = *fork {
|
||||
if e.is(name.as_ref(), namespace.as_ref()) {
|
||||
|
|
@ -690,7 +708,11 @@ impl Element {
|
|||
/// assert!(elem.remove_child("a", "ns").is_none());
|
||||
/// assert!(elem.remove_child("inexistent", "inexistent").is_none());
|
||||
/// ```
|
||||
pub fn remove_child<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<Element> {
|
||||
pub fn remove_child<N: AsRef<str>, NS: AsRef<str>>(
|
||||
&mut self,
|
||||
name: N,
|
||||
namespace: NS,
|
||||
) -> Option<Element> {
|
||||
let name = name.as_ref();
|
||||
let namespace = namespace.as_ref();
|
||||
let idx = self.children.iter().position(|x| {
|
||||
|
|
@ -715,25 +737,24 @@ fn split_element_name<S: AsRef<str>>(s: S) -> Result<(Option<String>, String)> {
|
|||
|
||||
fn build_element<R: BufRead>(reader: &EventReader<R>, event: &BytesStart) -> Result<Element> {
|
||||
let mut namespaces = BTreeMap::new();
|
||||
let attributes = event.attributes()
|
||||
let attributes = event
|
||||
.attributes()
|
||||
.map(|o| {
|
||||
let o = o?;
|
||||
let key = str::from_utf8(o.key)?.to_owned();
|
||||
let value = o.unescape_and_decode_value(reader)?;
|
||||
Ok((key, value))
|
||||
})
|
||||
.filter(|o| {
|
||||
match *o {
|
||||
Ok((ref key, ref value)) if key == "xmlns" => {
|
||||
namespaces.insert(None, value.to_owned());
|
||||
false
|
||||
},
|
||||
Ok((ref key, ref value)) if key.starts_with("xmlns:") => {
|
||||
namespaces.insert(Some(key[6..].to_owned()), value.to_owned());
|
||||
false
|
||||
},
|
||||
_ => true,
|
||||
.filter(|o| match *o {
|
||||
Ok((ref key, ref value)) if key == "xmlns" => {
|
||||
namespaces.insert(None, value.to_owned());
|
||||
false
|
||||
}
|
||||
Ok((ref key, ref value)) if key.starts_with("xmlns:") => {
|
||||
namespaces.insert(Some(key[6..].to_owned()), value.to_owned());
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
})
|
||||
.collect::<Result<BTreeMap<String, String>>>()?;
|
||||
|
||||
|
|
@ -861,7 +882,11 @@ impl ElementBuilder {
|
|||
}
|
||||
|
||||
/// Sets an attribute.
|
||||
pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
|
||||
pub fn attr<S: Into<String>, V: IntoAttributeValue>(
|
||||
mut self,
|
||||
name: S,
|
||||
value: V,
|
||||
) -> ElementBuilder {
|
||||
self.root.set_attr(name, value);
|
||||
self
|
||||
}
|
||||
|
|
@ -873,7 +898,10 @@ impl ElementBuilder {
|
|||
}
|
||||
|
||||
/// Appends an iterator of things implementing `Into<Node>` into the tree.
|
||||
pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(mut self, iter: I) -> ElementBuilder {
|
||||
pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
|
||||
mut self,
|
||||
iter: I,
|
||||
) -> ElementBuilder {
|
||||
for node in iter {
|
||||
self.root.append_node(node.into());
|
||||
}
|
||||
|
|
@ -903,11 +931,13 @@ mod tests {
|
|||
fn test_element_new() {
|
||||
use std::iter::FromIterator;
|
||||
|
||||
let elem = Element::new( "name".to_owned()
|
||||
, None
|
||||
, Some("namespace".to_owned())
|
||||
, BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
|
||||
, Vec::new() );
|
||||
let elem = Element::new(
|
||||
"name".to_owned(),
|
||||
None,
|
||||
Some("namespace".to_owned()),
|
||||
BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()),
|
||||
Vec::new(),
|
||||
);
|
||||
|
||||
assert_eq!(elem.name(), "name");
|
||||
assert_eq!(elem.ns(), Some("namespace".to_owned()));
|
||||
|
|
@ -932,12 +962,8 @@ mod tests {
|
|||
let mut reader = EventReader::from_str(xml);
|
||||
let elem = Element::from_reader(&mut reader);
|
||||
|
||||
let nested = Element::builder("bar")
|
||||
.attr("baz", "qxx")
|
||||
.build();
|
||||
let elem2 = Element::builder("foo")
|
||||
.append(nested)
|
||||
.build();
|
||||
let nested = Element::builder("bar").attr("baz", "qxx").build();
|
||||
let elem2 = Element::builder("foo").append(nested).build();
|
||||
|
||||
assert_eq!(elem.unwrap(), elem2);
|
||||
}
|
||||
|
|
@ -948,18 +974,15 @@ mod tests {
|
|||
let mut reader = EventReader::from_str(xml);
|
||||
let elem = Element::from_reader(&mut reader);
|
||||
|
||||
let nested = Element::builder("prefix:bar")
|
||||
.attr("baz", "qxx")
|
||||
.build();
|
||||
let elem2 = Element::builder("foo")
|
||||
.append(nested)
|
||||
.build();
|
||||
let nested = Element::builder("prefix:bar").attr("baz", "qxx").build();
|
||||
let elem2 = Element::builder("foo").append(nested).build();
|
||||
|
||||
assert_eq!(elem.unwrap(), elem2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_spectest_xml() { // From: https://gitlab.com/lumi/minidom-rs/issues/8
|
||||
fn parses_spectest_xml() {
|
||||
// From: https://gitlab.com/lumi/minidom-rs/issues/8
|
||||
let xml = r#"
|
||||
<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
|
||||
<rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
|
||||
|
|
|
|||
|
|
@ -52,11 +52,18 @@ impl std::fmt::Display for Error {
|
|||
Error::XmlError(e) => write!(fmt, "XML error: {}", e),
|
||||
Error::Utf8Error(e) => write!(fmt, "UTF-8 error: {}", e),
|
||||
Error::IoError(e) => write!(fmt, "IO error: {}", e),
|
||||
Error::EndOfDocument => write!(fmt, "the end of the document has been reached prematurely"),
|
||||
Error::InvalidElementClosed => write!(fmt, "the XML is invalid, an element was wrongly closed"),
|
||||
Error::EndOfDocument => {
|
||||
write!(fmt, "the end of the document has been reached prematurely")
|
||||
}
|
||||
Error::InvalidElementClosed => {
|
||||
write!(fmt, "the XML is invalid, an element was wrongly closed")
|
||||
}
|
||||
Error::InvalidElement => write!(fmt, "the XML element is invalid"),
|
||||
#[cfg(not(comments))]
|
||||
Error::CommentsDisabled => write!(fmt, "a comment has been found even though comments are disabled by feature"),
|
||||
Error::CommentsDisabled => write!(
|
||||
fmt,
|
||||
"a comment has been found even though comments are disabled by feature"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,15 +66,16 @@
|
|||
|
||||
pub use quick_xml;
|
||||
|
||||
pub mod error;
|
||||
pub mod element;
|
||||
pub mod convert;
|
||||
pub mod node;
|
||||
pub mod element;
|
||||
pub mod error;
|
||||
mod namespace_set;
|
||||
pub mod node;
|
||||
|
||||
#[cfg(test)] mod tests;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use error::{Error, Result};
|
||||
pub use element::{Element, Children, ChildrenMut, ElementBuilder};
|
||||
pub use node::Node;
|
||||
pub use convert::IntoAttributeValue;
|
||||
pub use element::{Children, ChildrenMut, Element, ElementBuilder};
|
||||
pub use error::{Error, Result};
|
||||
pub use node::Node;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct NamespaceSet {
|
||||
parent: RefCell<Option<Rc<NamespaceSet>>>,
|
||||
|
|
@ -23,10 +22,15 @@ impl fmt::Debug for NamespaceSet {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "NamespaceSet(")?;
|
||||
for (prefix, namespace) in &self.namespaces {
|
||||
write!(f, "xmlns{}={:?}, ", match prefix {
|
||||
None => String::new(),
|
||||
Some(prefix) => format!(":{}", prefix),
|
||||
}, namespace)?;
|
||||
write!(
|
||||
f,
|
||||
"xmlns{}={:?}, ",
|
||||
match prefix {
|
||||
None => String::new(),
|
||||
Some(prefix) => format!(":{}", prefix),
|
||||
},
|
||||
namespace
|
||||
)?;
|
||||
}
|
||||
write!(f, "parent: {:?})", *self.parent.borrow())
|
||||
}
|
||||
|
|
@ -42,20 +46,17 @@ impl NamespaceSet {
|
|||
Some(ns) => Some(ns.clone()),
|
||||
None => match *self.parent.borrow() {
|
||||
None => None,
|
||||
Some(ref parent) => parent.get(prefix)
|
||||
Some(ref parent) => parent.get(prefix),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has<NS: AsRef<str>>(&self, prefix: &Option<String>, wanted_ns: NS) -> bool {
|
||||
match self.namespaces.get(prefix) {
|
||||
Some(ns) =>
|
||||
ns == wanted_ns.as_ref(),
|
||||
Some(ns) => ns == wanted_ns.as_ref(),
|
||||
None => match *self.parent.borrow() {
|
||||
None =>
|
||||
false,
|
||||
Some(ref parent) =>
|
||||
parent.has(prefix, wanted_ns),
|
||||
None => false,
|
||||
Some(ref parent) => parent.has(prefix, wanted_ns),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +66,6 @@ impl NamespaceSet {
|
|||
let new_set = parent;
|
||||
*parent_ns = Some(new_set);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl From<BTreeMap<Option<String>, String>> for NamespaceSet {
|
||||
|
|
@ -132,7 +132,10 @@ mod tests {
|
|||
#[test]
|
||||
fn get_has_prefixed() {
|
||||
let namespaces = NamespaceSet::from(("x".to_owned(), "bar".to_owned()));
|
||||
assert_eq!(namespaces.get(&Some("x".to_owned())), Some("bar".to_owned()));
|
||||
assert_eq!(
|
||||
namespaces.get(&Some("x".to_owned())),
|
||||
Some("bar".to_owned())
|
||||
);
|
||||
assert!(namespaces.has(&Some("x".to_owned()), "bar"));
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +157,10 @@ mod tests {
|
|||
for _ in 0..1000 {
|
||||
let namespaces = NamespaceSet::default();
|
||||
namespaces.set_parent(Rc::new(parent));
|
||||
assert_eq!(namespaces.get(&Some("x".to_owned())), Some("bar".to_owned()));
|
||||
assert_eq!(
|
||||
namespaces.get(&Some("x".to_owned())),
|
||||
Some("bar".to_owned())
|
||||
);
|
||||
assert!(namespaces.has(&Some("x".to_owned()), "bar"));
|
||||
parent = namespaces;
|
||||
}
|
||||
|
|
@ -163,7 +169,10 @@ mod tests {
|
|||
#[test]
|
||||
fn debug_looks_correct() {
|
||||
let parent = NamespaceSet::from("http://www.w3.org/2000/svg".to_owned());
|
||||
let namespaces = NamespaceSet::from(("xhtml".to_owned(), "http://www.w3.org/1999/xhtml".to_owned()));
|
||||
let namespaces = NamespaceSet::from((
|
||||
"xhtml".to_owned(),
|
||||
"http://www.w3.org/1999/xhtml".to_owned(),
|
||||
));
|
||||
namespaces.set_parent(Rc::new(parent));
|
||||
assert_eq!(format!("{:?}", namespaces), "NamespaceSet(xmlns:xhtml=\"http://www.w3.org/1999/xhtml\", parent: Some(NamespaceSet(xmlns=\"http://www.w3.org/2000/svg\", parent: None)))");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use crate::error::Result;
|
|||
|
||||
use std::io::Write;
|
||||
|
||||
use quick_xml::events::{BytesText, Event};
|
||||
use quick_xml::Writer as EventWriter;
|
||||
use quick_xml::events::{Event, BytesText};
|
||||
|
||||
/// A node in an element tree.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
@ -166,16 +166,16 @@ impl Node {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(crate) fn write_to_inner<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()>{
|
||||
pub(crate) fn write_to_inner<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
|
||||
match *self {
|
||||
Node::Element(ref elmt) => elmt.write_to_inner(writer)?,
|
||||
Node::Text(ref s) => {
|
||||
writer.write_event(Event::Text(BytesText::from_plain_str(s)))?;
|
||||
},
|
||||
}
|
||||
#[cfg(feature = "comments")]
|
||||
Node::Comment(ref s) => {
|
||||
writer.write_event(Event::Comment(BytesText::from_plain_str(s)))?;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -6,20 +6,18 @@ const TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root
|
|||
|
||||
fn build_test_tree() -> Element {
|
||||
let mut root = Element::builder("root")
|
||||
.ns("root_ns")
|
||||
.attr("xml:lang", "en")
|
||||
.attr("a", "b")
|
||||
.build();
|
||||
.ns("root_ns")
|
||||
.attr("xml:lang", "en")
|
||||
.attr("a", "b")
|
||||
.build();
|
||||
root.append_text_node("meow");
|
||||
let child = Element::builder("child")
|
||||
.attr("c", "d")
|
||||
.build();
|
||||
let child = Element::builder("child").attr("c", "d").build();
|
||||
root.append_child(child);
|
||||
let other_child = Element::builder("child")
|
||||
.ns("child_ns")
|
||||
.attr("d", "e")
|
||||
.attr("xml:lang", "fr")
|
||||
.build();
|
||||
.ns("child_ns")
|
||||
.attr("d", "e")
|
||||
.attr("xml:lang", "fr")
|
||||
.build();
|
||||
root.append_child(other_child);
|
||||
root.append_text_node("nya");
|
||||
root
|
||||
|
|
@ -43,7 +41,10 @@ fn build_comment_test_tree() -> Element {
|
|||
#[test]
|
||||
fn reader_works() {
|
||||
let mut reader = Reader::from_str(TEST_STRING);
|
||||
assert_eq!(Element::from_reader(&mut reader).unwrap(), build_test_tree());
|
||||
assert_eq!(
|
||||
Element::from_reader(&mut reader).unwrap(),
|
||||
build_test_tree()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -58,40 +59,38 @@ fn writer_works() {
|
|||
|
||||
#[test]
|
||||
fn writer_escapes_attributes() {
|
||||
let root = Element::builder("root")
|
||||
.attr("a", "\"Air\" quotes")
|
||||
.build();
|
||||
let root = Element::builder("root").attr("a", "\"Air\" quotes").build();
|
||||
let mut writer = Vec::new();
|
||||
{
|
||||
root.write_to(&mut writer).unwrap();
|
||||
}
|
||||
assert_eq!(String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root a=""Air" quotes"/>"#
|
||||
assert_eq!(
|
||||
String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root a=""Air" quotes"/>"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writer_escapes_text() {
|
||||
let root = Element::builder("root")
|
||||
.append("<3")
|
||||
.build();
|
||||
let root = Element::builder("root").append("<3").build();
|
||||
let mut writer = Vec::new();
|
||||
{
|
||||
root.write_to(&mut writer).unwrap();
|
||||
}
|
||||
assert_eq!(String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root><3</root>"#
|
||||
assert_eq!(
|
||||
String::from_utf8(writer).unwrap(),
|
||||
r#"<?xml version="1.0" encoding="utf-8"?><root><3</root>"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builder_works() {
|
||||
let elem = Element::builder("a")
|
||||
.ns("b")
|
||||
.attr("c", "d")
|
||||
.append(Element::builder("child"))
|
||||
.append("e")
|
||||
.build();
|
||||
.ns("b")
|
||||
.attr("c", "d")
|
||||
.append(Element::builder("child"))
|
||||
.append("e")
|
||||
.build();
|
||||
assert_eq!(elem.name(), "a");
|
||||
assert_eq!(elem.ns(), Some("b".to_owned()));
|
||||
assert_eq!(elem.attr("c"), Some("d"));
|
||||
|
|
@ -115,10 +114,22 @@ fn get_child_works() {
|
|||
let root = build_test_tree();
|
||||
assert_eq!(root.get_child("child", "inexistent_ns"), None);
|
||||
assert_eq!(root.get_child("not_a_child", "root_ns"), None);
|
||||
assert!(root.get_child("child", "root_ns").unwrap().is("child", "root_ns"));
|
||||
assert!(root.get_child("child", "child_ns").unwrap().is("child", "child_ns"));
|
||||
assert_eq!(root.get_child("child", "root_ns").unwrap().attr("c"), Some("d"));
|
||||
assert_eq!(root.get_child("child", "child_ns").unwrap().attr("d"), Some("e"));
|
||||
assert!(root
|
||||
.get_child("child", "root_ns")
|
||||
.unwrap()
|
||||
.is("child", "root_ns"));
|
||||
assert!(root
|
||||
.get_child("child", "child_ns")
|
||||
.unwrap()
|
||||
.is("child", "child_ns"));
|
||||
assert_eq!(
|
||||
root.get_child("child", "root_ns").unwrap().attr("c"),
|
||||
Some("d")
|
||||
);
|
||||
assert_eq!(
|
||||
root.get_child("child", "child_ns").unwrap().attr("d"),
|
||||
Some("e")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -130,9 +141,14 @@ fn namespace_propagation_works() {
|
|||
root.append_child(child);
|
||||
|
||||
assert_eq!(root.get_child("child", "root_ns").unwrap().ns(), root.ns());
|
||||
assert_eq!(root.get_child("child", "root_ns").unwrap()
|
||||
.get_child("grandchild", "root_ns").unwrap()
|
||||
.ns(), root.ns());
|
||||
assert_eq!(
|
||||
root.get_child("child", "root_ns")
|
||||
.unwrap()
|
||||
.get_child("grandchild", "root_ns")
|
||||
.unwrap()
|
||||
.ns(),
|
||||
root.ns()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -151,7 +167,13 @@ fn namespace_attributes_works() {
|
|||
let mut reader = Reader::from_str(TEST_STRING);
|
||||
let root = Element::from_reader(&mut reader).unwrap();
|
||||
assert_eq!("en", root.attr("xml:lang").unwrap());
|
||||
assert_eq!("fr", root.get_child("child", "child_ns").unwrap().attr("xml:lang").unwrap());
|
||||
assert_eq!(
|
||||
"fr",
|
||||
root.get_child("child", "child_ns")
|
||||
.unwrap()
|
||||
.attr("xml:lang")
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -174,14 +196,20 @@ fn namespace_simple() {
|
|||
#[test]
|
||||
fn namespace_prefixed() {
|
||||
let elem: Element = "<stream:features xmlns:stream='http://etherx.jabber.org/streams'/>"
|
||||
.parse().unwrap();
|
||||
.parse()
|
||||
.unwrap();
|
||||
assert_eq!(elem.name(), "features");
|
||||
assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned()));
|
||||
assert_eq!(
|
||||
elem.ns(),
|
||||
Some("http://etherx.jabber.org/streams".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_inherited_simple() {
|
||||
let elem: Element = "<stream xmlns='jabber:client'><message/></stream>".parse().unwrap();
|
||||
let elem: Element = "<stream xmlns='jabber:client'><message/></stream>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
assert_eq!(elem.name(), "stream");
|
||||
assert_eq!(elem.ns(), Some("jabber:client".to_owned()));
|
||||
let child = elem.children().next().unwrap();
|
||||
|
|
@ -194,7 +222,10 @@ fn namespace_inherited_prefixed1() {
|
|||
let elem: Element = "<stream:features xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'><message/></stream:features>"
|
||||
.parse().unwrap();
|
||||
assert_eq!(elem.name(), "features");
|
||||
assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned()));
|
||||
assert_eq!(
|
||||
elem.ns(),
|
||||
Some("http://etherx.jabber.org/streams".to_owned())
|
||||
);
|
||||
let child = elem.children().next().unwrap();
|
||||
assert_eq!(child.name(), "message");
|
||||
assert_eq!(child.ns(), Some("jabber:client".to_owned()));
|
||||
|
|
@ -205,7 +236,10 @@ fn namespace_inherited_prefixed2() {
|
|||
let elem: Element = "<stream xmlns='http://etherx.jabber.org/streams' xmlns:jabber='jabber:client'><jabber:message/></stream>"
|
||||
.parse().unwrap();
|
||||
assert_eq!(elem.name(), "stream");
|
||||
assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned()));
|
||||
assert_eq!(
|
||||
elem.ns(),
|
||||
Some("http://etherx.jabber.org/streams".to_owned())
|
||||
);
|
||||
let child = elem.children().next().unwrap();
|
||||
assert_eq!(child.name(), "message");
|
||||
assert_eq!(child.ns(), Some("jabber:client".to_owned()));
|
||||
|
|
@ -215,7 +249,10 @@ fn namespace_inherited_prefixed2() {
|
|||
#[test]
|
||||
fn read_comments() {
|
||||
let mut reader = Reader::from_str(COMMENT_TEST_STRING);
|
||||
assert_eq!(Element::from_reader(&mut reader).unwrap(), build_comment_test_tree());
|
||||
assert_eq!(
|
||||
Element::from_reader(&mut reader).unwrap(),
|
||||
build_comment_test_tree()
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "comments")]
|
||||
|
|
@ -233,12 +270,12 @@ fn write_comments() {
|
|||
fn xml_error() {
|
||||
match "<a></b>".parse::<Element>() {
|
||||
Err(crate::error::Error::XmlError(_)) => (),
|
||||
err => panic!("No or wrong error: {:?}", err)
|
||||
err => panic!("No or wrong error: {:?}", err),
|
||||
}
|
||||
|
||||
match "<a></".parse::<Element>() {
|
||||
Err(crate::error::Error::XmlError(_)) => (),
|
||||
err => panic!("No or wrong error: {:?}", err)
|
||||
err => panic!("No or wrong error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,6 +283,6 @@ fn xml_error() {
|
|||
fn invalid_element_error() {
|
||||
match "<a:b:c>".parse::<Element>() {
|
||||
Err(crate::error::Error::InvalidElement) => (),
|
||||
err => panic!("No or wrong error: {:?}", err)
|
||||
err => panic!("No or wrong error: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue