minidom: Add NSChoice enum to extent element.is and .has_ns API
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
276dc4fcb2
commit
362ceae922
4 changed files with 62 additions and 8 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
Version XXX, released YYY:
|
Version XXX, released YYY:
|
||||||
* Changes
|
* Changes
|
||||||
* Update edition to 2018
|
* Update edition to 2018
|
||||||
|
* Add NSChoice enum to allow comparing NSs differently
|
||||||
* Fixes
|
* Fixes
|
||||||
* Update old CI configuration with newer Rust images
|
* Update old CI configuration with newer Rust images
|
||||||
Version 0.11.1, released 2019-09-06:
|
Version 0.11.1, released 2019-09-06:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::convert::IntoAttributeValue;
|
use crate::convert::IntoAttributeValue;
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use crate::namespace_set::NamespaceSet;
|
use crate::namespace_set::{NamespaceSet, NSChoice};
|
||||||
use crate::node::Node;
|
use crate::node::Node;
|
||||||
|
|
||||||
use std::collections::{btree_map, BTreeMap};
|
use std::collections::{btree_map, BTreeMap};
|
||||||
|
|
@ -246,7 +246,7 @@ impl Element {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use minidom::Element;
|
/// use minidom::{Element, NSChoice};
|
||||||
///
|
///
|
||||||
/// let elem = Element::builder("name").ns("namespace").build();
|
/// let elem = Element::builder("name").ns("namespace").build();
|
||||||
///
|
///
|
||||||
|
|
@ -254,8 +254,19 @@ impl Element {
|
||||||
/// assert_eq!(elem.is("name", "wrong"), false);
|
/// assert_eq!(elem.is("name", "wrong"), false);
|
||||||
/// assert_eq!(elem.is("wrong", "namespace"), false);
|
/// assert_eq!(elem.is("wrong", "namespace"), false);
|
||||||
/// assert_eq!(elem.is("wrong", "wrong"), false);
|
/// assert_eq!(elem.is("wrong", "wrong"), false);
|
||||||
|
///
|
||||||
|
/// assert_eq!(elem.is("name", NSChoice::None), false);
|
||||||
|
/// assert_eq!(elem.is("name", NSChoice::OneOf("namespace")), true);
|
||||||
|
/// assert_eq!(elem.is("name", NSChoice::OneOf("foo")), false);
|
||||||
|
/// assert_eq!(elem.is("name", NSChoice::AnyOf(vec!["foo", "namespace"])), true);
|
||||||
|
/// assert_eq!(elem.is("name", NSChoice::Any), true);
|
||||||
|
///
|
||||||
|
/// let elem2 = Element::builder("name").build();
|
||||||
|
///
|
||||||
|
/// assert_eq!(elem2.is("name", NSChoice::None), true);
|
||||||
|
/// assert_eq!(elem2.is("name", NSChoice::Any), true);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
|
pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
|
||||||
self.name == name.as_ref() && self.has_ns(namespace)
|
self.name == name.as_ref() && self.has_ns(namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,14 +275,25 @@ impl Element {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use minidom::Element;
|
/// use minidom::{Element, NSChoice};
|
||||||
///
|
///
|
||||||
/// let elem = Element::builder("name").ns("namespace").build();
|
/// let elem = Element::builder("name").ns("namespace").build();
|
||||||
///
|
///
|
||||||
/// assert_eq!(elem.has_ns("namespace"), true);
|
/// assert_eq!(elem.has_ns("namespace"), true);
|
||||||
/// assert_eq!(elem.has_ns("wrong"), false);
|
/// assert_eq!(elem.has_ns("wrong"), false);
|
||||||
|
///
|
||||||
|
/// assert_eq!(elem.has_ns(NSChoice::None), false);
|
||||||
|
/// assert_eq!(elem.has_ns(NSChoice::OneOf("namespace")), true);
|
||||||
|
/// assert_eq!(elem.has_ns(NSChoice::OneOf("foo")), false);
|
||||||
|
/// assert_eq!(elem.has_ns(NSChoice::AnyOf(vec!["foo", "namespace"])), true);
|
||||||
|
/// assert_eq!(elem.has_ns(NSChoice::Any), true);
|
||||||
|
///
|
||||||
|
/// let elem2 = Element::builder("name").build();
|
||||||
|
///
|
||||||
|
/// assert_eq!(elem2.has_ns(NSChoice::None), true);
|
||||||
|
/// assert_eq!(elem2.has_ns(NSChoice::Any), true);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn has_ns<NS: AsRef<str>>(&self, namespace: NS) -> bool {
|
pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
|
||||||
self.namespaces.has(&self.prefix, namespace)
|
self.namespaces.has(&self.prefix, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,6 @@ mod tests;
|
||||||
|
|
||||||
pub use convert::IntoAttributeValue;
|
pub use convert::IntoAttributeValue;
|
||||||
pub use element::{Children, ChildrenMut, Element, ElementBuilder};
|
pub use element::{Children, ChildrenMut, Element, ElementBuilder};
|
||||||
|
pub use namespace_set::NSChoice;
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use node::Node;
|
pub use node::Node;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,25 @@ use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
/// Use to compare namespaces
|
||||||
|
pub enum NSChoice<'a> {
|
||||||
|
/// The element must have no namespace
|
||||||
|
None,
|
||||||
|
/// The element's namespace must match the specified namespace
|
||||||
|
OneOf(&'a str),
|
||||||
|
/// The element's namespace must be in the specified vector
|
||||||
|
AnyOf(Vec<&'a str>),
|
||||||
|
/// The element can have any namespace, or no namespace
|
||||||
|
Any,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for NSChoice<'a> {
|
||||||
|
fn from(ns: &'a str) -> NSChoice<'a> {
|
||||||
|
NSChoice::OneOf(ns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub struct NamespaceSet {
|
pub struct NamespaceSet {
|
||||||
parent: RefCell<Option<Rc<NamespaceSet>>>,
|
parent: RefCell<Option<Rc<NamespaceSet>>>,
|
||||||
|
|
@ -51,11 +70,22 @@ impl NamespaceSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has<NS: AsRef<str>>(&self, prefix: &Option<String>, wanted_ns: NS) -> bool {
|
fn compare_ns<'a>(&self, ns: Option<&str>, wanted_ns: NSChoice<'a>) -> bool {
|
||||||
|
match (ns, wanted_ns) {
|
||||||
|
(None, NSChoice::None) | (None, NSChoice::Any) => true,
|
||||||
|
(None, NSChoice::OneOf(_)) | (None, NSChoice::AnyOf(_)) => false,
|
||||||
|
(Some(_), NSChoice::None) => false,
|
||||||
|
(Some(_), NSChoice::Any) => true,
|
||||||
|
(Some(ns), NSChoice::OneOf(wanted_ns)) => ns == wanted_ns,
|
||||||
|
(Some(ns), NSChoice::AnyOf(wanted_nss)) => wanted_nss.iter().any(|w| &ns == w),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has<'a, NS: Into<NSChoice<'a>>>(&self, prefix: &Option<String>, wanted_ns: NS) -> bool {
|
||||||
match self.namespaces.get(prefix) {
|
match self.namespaces.get(prefix) {
|
||||||
Some(ns) => ns == wanted_ns.as_ref(),
|
Some(ns) => self.compare_ns(Some(ns), wanted_ns.into()),
|
||||||
None => match *self.parent.borrow() {
|
None => match *self.parent.borrow() {
|
||||||
None => false,
|
None => self.compare_ns(None, wanted_ns.into()),
|
||||||
Some(ref parent) => parent.has(prefix, wanted_ns),
|
Some(ref parent) => parent.has(prefix, wanted_ns),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue