Make comments optional.

Add a default "comments" feature to transform comments into errors when
unset.

This is so that XMPP implementations don’t have to care about comments,
as they can’t happen in the stream.
This commit is contained in:
Emmanuel Gil Peyrot 2019-08-22 18:04:47 +02:00
commit a91252c861
6 changed files with 32 additions and 1 deletions

View file

@ -1,6 +1,7 @@
Version XXX, released YYY: Version XXX, released YYY:
* Changes * Changes
* Update to quick-xml 0.15 * Update to quick-xml 0.15
* Add a default "comments" feature to transform comments into errors when unset.
Version 0.11.0, released 2019-06-14: Version 0.11.0, released 2019-06-14:
* Breaking * Breaking
* Get rid of IntoElements, replace with `Into<Node>` and `<T: Into<Node> IntoIterator<Item = T>>` * Get rid of IntoElements, replace with `Into<Node>` and `<T: Into<Node> IntoIterator<Item = T>>`

View file

@ -23,3 +23,7 @@ gitlab = { repository = "lumi/minidom-rs" }
quick-xml = "0.15" quick-xml = "0.15"
failure = "0.1.1" failure = "0.1.1"
failure_derive = "0.1.1" failure_derive = "0.1.1"
[features]
default = ["comments"]
comments = []

View file

@ -283,9 +283,14 @@ impl Element {
Event::Eof => { Event::Eof => {
return Err(Error::EndOfDocument); return Err(Error::EndOfDocument);
}, },
#[cfg(not(feature = "comments"))]
Event::Comment { .. } => {
return Err(Error::CommentsDisabled);
}
#[cfg(feature = "comments")]
Event::Comment { .. } => (),
Event::Text { .. } | Event::Text { .. } |
Event::End { .. } | Event::End { .. } |
Event::Comment { .. } |
Event::CData { .. } | Event::CData { .. } |
Event::Decl { .. } | Event::Decl { .. } |
Event::PI { .. } | Event::PI { .. } |
@ -361,6 +366,9 @@ impl Element {
Event::Eof => { Event::Eof => {
break; break;
}, },
#[cfg(not(feature = "comments"))]
Event::Comment(_) => return Err(Error::CommentsDisabled),
#[cfg(feature = "comments")]
Event::Comment(s) => { Event::Comment(s) => {
let comment = reader.decode(&s).into_owned(); let comment = reader.decode(&s).into_owned();
if comment != "" { if comment != "" {
@ -569,6 +577,7 @@ impl Element {
/// ///
/// elem.append_comment_node("comment"); /// elem.append_comment_node("comment");
/// ``` /// ```
#[cfg(feature = "comments")]
pub fn append_comment_node<S: Into<String>>(&mut self, child: S) { pub fn append_comment_node<S: Into<String>>(&mut self, child: S) {
self.children.push(Node::Comment(child.into())); self.children.push(Node::Comment(child.into()));
} }

View file

@ -28,6 +28,11 @@ pub enum Error {
/// An error which is returned when an elemet's name contains more than one colon /// An error which is returned when an elemet's name contains more than one colon
#[fail(display = "the XML element is invalid")] #[fail(display = "the XML element is invalid")]
InvalidElement, InvalidElement,
/// An error which is returned when a comment is to be parsed by minidom
#[cfg(not(comments))]
#[fail(display = "a comment has been found even though comments are disabled by feature")]
CommentsDisabled,
} }
impl From<::quick_xml::Error> for Error { impl From<::quick_xml::Error> for Error {

View file

@ -16,6 +16,7 @@ pub enum Node {
Element(Element), Element(Element),
/// A text node. /// A text node.
Text(String), Text(String),
#[cfg(feature = "comments")]
/// A comment node. /// A comment node.
Comment(String), Comment(String),
} }
@ -39,6 +40,7 @@ impl Node {
match *self { match *self {
Node::Element(ref e) => Some(e), Node::Element(ref e) => Some(e),
Node::Text(_) => None, Node::Text(_) => None,
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -61,6 +63,7 @@ impl Node {
match *self { match *self {
Node::Element(ref mut e) => Some(e), Node::Element(ref mut e) => Some(e),
Node::Text(_) => None, Node::Text(_) => None,
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -83,6 +86,7 @@ impl Node {
match self { match self {
Node::Element(e) => Some(e), Node::Element(e) => Some(e),
Node::Text(_) => None, Node::Text(_) => None,
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -105,6 +109,7 @@ impl Node {
match *self { match *self {
Node::Element(_) => None, Node::Element(_) => None,
Node::Text(ref s) => Some(s), Node::Text(ref s) => Some(s),
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -133,6 +138,7 @@ impl Node {
match *self { match *self {
Node::Element(_) => None, Node::Element(_) => None,
Node::Text(ref mut s) => Some(s), Node::Text(ref mut s) => Some(s),
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -155,6 +161,7 @@ impl Node {
match self { match self {
Node::Element(_) => None, Node::Element(_) => None,
Node::Text(s) => Some(s), Node::Text(s) => Some(s),
#[cfg(feature = "comments")]
Node::Comment(_) => None, Node::Comment(_) => None,
} }
} }
@ -166,6 +173,7 @@ impl Node {
Node::Text(ref s) => { Node::Text(ref s) => {
writer.write_event(Event::Text(BytesText::from_plain_str(s)))?; writer.write_event(Event::Text(BytesText::from_plain_str(s)))?;
}, },
#[cfg(feature = "comments")]
Node::Comment(ref s) => { Node::Comment(ref s) => {
writer.write_event(Event::Comment(BytesText::from_plain_str(s)))?; writer.write_event(Event::Comment(BytesText::from_plain_str(s)))?;
}, },

View file

@ -27,8 +27,10 @@ fn build_test_tree() -> Element {
root root
} }
#[cfg(feature = "comments")]
const COMMENT_TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root><!--This is a child.--><child attr="val"><!--This is a grandchild.--><grandchild/></child></root>"#; const COMMENT_TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root><!--This is a child.--><child attr="val"><!--This is a grandchild.--><grandchild/></child></root>"#;
#[cfg(feature = "comments")]
fn build_comment_test_tree() -> Element { fn build_comment_test_tree() -> Element {
let mut root = Element::builder("root").build(); let mut root = Element::builder("root").build();
root.append_comment_node("This is a child."); root.append_comment_node("This is a child.");
@ -211,12 +213,14 @@ fn namespace_inherited_prefixed2() {
assert_eq!(child.ns(), Some("jabber:client".to_owned())); assert_eq!(child.ns(), Some("jabber:client".to_owned()));
} }
#[cfg(feature = "comments")]
#[test] #[test]
fn read_comments() { fn read_comments() {
let mut reader = Reader::from_str(COMMENT_TEST_STRING); 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")]
#[test] #[test]
fn write_comments() { fn write_comments() {
let root = build_comment_test_tree(); let root = build_comment_test_tree();