minidom: Make ElementBuilder::prefix fail on adding duplicate prefix

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2020-03-29 21:35:53 +02:00
parent 770dff7cb0
commit 937e2380b9
3 changed files with 21 additions and 14 deletions

View file

@ -194,7 +194,7 @@ impl Element {
name.into(), name.into(),
namespace.into(), namespace.into(),
None, None,
BTreeMap::new(), None,
BTreeMap::new(), BTreeMap::new(),
Vec::new(), Vec::new(),
) )
@ -987,10 +987,12 @@ pub struct ElementBuilder {
impl ElementBuilder { impl ElementBuilder {
/// Sets a custom prefix. It is not possible to set the same prefix twice. /// Sets a custom prefix. It is not possible to set the same prefix twice.
pub fn prefix<S: Into<Namespace>>(mut self, prefix: Prefix, namespace: S) -> ElementBuilder { pub fn prefix<S: Into<Namespace>>(mut self, prefix: Prefix, namespace: S) -> Result<ElementBuilder> {
// TODO: Make this actually send back an error when a duplicate prefix is added. if let Some(_) = self.root.prefixes.get(&prefix) {
return Err(Error::DuplicatePrefix);
}
self.root.prefixes.insert(prefix, namespace.into()); self.root.prefixes.insert(prefix, namespace.into());
self Ok(self)
} }
/// Sets an attribute. /// Sets an attribute.

View file

@ -44,6 +44,9 @@ pub enum Error {
/// An error which is returned when a comment is to be parsed by minidom /// An error which is returned when a comment is to be parsed by minidom
NoComments, NoComments,
/// An error which is returned when a prefixed is defined twice
DuplicatePrefix,
} }
impl StdError for Error { impl StdError for Error {
@ -58,6 +61,7 @@ impl StdError for Error {
Error::InvalidPrefix => None, Error::InvalidPrefix => None,
Error::MissingNamespace => None, Error::MissingNamespace => None,
Error::NoComments => None, Error::NoComments => None,
Error::DuplicatePrefix => None,
} }
} }
} }
@ -84,6 +88,7 @@ impl std::fmt::Display for Error {
fmt, fmt,
"a comment has been found even though comments are forbidden" "a comment has been found even though comments are forbidden"
), ),
Error::DuplicatePrefix => write!(fmt, "the prefix is already defined"),
} }
} }
} }

View file

@ -77,8 +77,8 @@ fn test_real_data() {
.append(correction) .append(correction)
.build(); .build();
let stream = Element::builder("stream", "http://etherx.jabber.org/streams") let stream = Element::builder("stream", "http://etherx.jabber.org/streams")
.prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams") .prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams").unwrap()
.prefix(None, "jabber:client") .prefix(None, "jabber:client").unwrap()
.append(message) .append(message)
.build(); .build();
println!("{}", String::from(&stream)); println!("{}", String::from(&stream));
@ -109,8 +109,8 @@ fn test_real_data() {
.append(pubsub) .append(pubsub)
.build(); .build();
let stream = Element::builder("stream", "http://etherx.jabber.org/streams") let stream = Element::builder("stream", "http://etherx.jabber.org/streams")
.prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams") .prefix(Some(String::from("stream")), "http://etherx.jabber.org/streams").unwrap()
.prefix(None, "jabber:client") .prefix(None, "jabber:client").unwrap()
.append(iq) .append(iq)
.build(); .build();
@ -141,8 +141,8 @@ fn writer_with_decl_works() {
#[test] #[test]
fn writer_with_prefix() { fn writer_with_prefix() {
let root = Element::builder("root", "ns1") let root = Element::builder("root", "ns1")
.prefix(Some(String::from("p1")), "ns1") .prefix(Some(String::from("p1")), "ns1").unwrap()
.prefix(None, "ns2") .prefix(None, "ns2").unwrap()
.build(); .build();
assert_eq!(String::from(&root), assert_eq!(String::from(&root),
r#"<p1:root xmlns="ns2" xmlns:p1="ns1"/>"#, r#"<p1:root xmlns="ns2" xmlns:p1="ns1"/>"#,
@ -168,7 +168,7 @@ fn writer_no_prefix_namespace_child() {
assert_eq!(String::from(&root), r#"<root xmlns="ns1"><child/></root>"#); assert_eq!(String::from(&root), r#"<root xmlns="ns1"><child/></root>"#);
let child = Element::builder("child", "ns2") let child = Element::builder("child", "ns2")
.prefix(None, "ns3") .prefix(None, "ns3").unwrap()
.build(); .build();
let root = Element::builder("root", "ns1") let root = Element::builder("root", "ns1")
.append(child) .append(child)
@ -181,7 +181,7 @@ fn writer_no_prefix_namespace_child() {
fn writer_prefix_namespace_child() { fn writer_prefix_namespace_child() {
let child = Element::builder("child", "ns1").build(); let child = Element::builder("child", "ns1").build();
let root = Element::builder("root", "ns1") let root = Element::builder("root", "ns1")
.prefix(Some(String::from("p1")), "ns1") .prefix(Some(String::from("p1")), "ns1").unwrap()
.append(child) .append(child)
.build(); .build();
assert_eq!(String::from(&root), r#"<p1:root xmlns:p1="ns1"><p1:child/></p1:root>"#); assert_eq!(String::from(&root), r#"<p1:root xmlns:p1="ns1"><p1:child/></p1:root>"#);
@ -193,8 +193,8 @@ fn writer_with_prefix_deduplicate() {
// .prefix(Some(String::from("p1")), "ns1") // .prefix(Some(String::from("p1")), "ns1")
.build(); .build();
let root = Element::builder("root", "ns1") let root = Element::builder("root", "ns1")
.prefix(Some(String::from("p1")), "ns1") .prefix(Some(String::from("p1")), "ns1").unwrap()
.prefix(None, "ns2") .prefix(None, "ns2").unwrap()
.append(child) .append(child)
.build(); .build();
assert_eq!(String::from(&root), assert_eq!(String::from(&root),