use super::error::XPathError;
use super::{DomNavigator, XmlNodeOrder};
pub fn same_node<N: DomNavigator>(a: &N, b: &N) -> bool {
match a.compare_position(b) {
XmlNodeOrder::Same => true,
XmlNodeOrder::Unknown => b.compare_position(a) == XmlNodeOrder::Same,
_ => false,
}
}
pub fn preceding_node<N: DomNavigator>(a: &N, b: &N) -> bool {
a.compare_position(b) == XmlNodeOrder::Before
}
pub fn following_node<N: DomNavigator>(a: &N, b: &N) -> bool {
a.compare_position(b) == XmlNodeOrder::After
}
pub fn get_root<N: DomNavigator>(node: &N) -> N {
let mut nav = node.clone();
nav.move_to_root();
nav
}
pub fn context_node<N: DomNavigator>(context: Option<&N>) -> Result<N, XPathError> {
context.cloned().ok_or_else(XPathError::context_undefined)
}
pub fn compare_document_order<N: DomNavigator>(a: &N, b: &N) -> std::cmp::Ordering {
match a.compare_position(b) {
XmlNodeOrder::Before => std::cmp::Ordering::Less,
XmlNodeOrder::Same => std::cmp::Ordering::Equal,
XmlNodeOrder::After => std::cmp::Ordering::Greater,
XmlNodeOrder::Unknown => {
match b.compare_position(a) {
XmlNodeOrder::Before => std::cmp::Ordering::Greater,
XmlNodeOrder::After => std::cmp::Ordering::Less,
_ => std::cmp::Ordering::Equal,
}
}
}
}
pub fn is_root<N: DomNavigator>(node: &N) -> bool {
let root = get_root(node);
same_node(node, &root)
}
pub fn is_ancestor<N: DomNavigator>(ancestor: &N, descendant: &N) -> bool {
let mut current = descendant.clone();
while current.move_to_parent() {
if same_node(¤t, ancestor) {
return true;
}
}
false
}
pub fn is_descendant<N: DomNavigator>(descendant: &N, ancestor: &N) -> bool {
is_ancestor(ancestor, descendant)
}
pub fn are_siblings<N: DomNavigator>(a: &N, b: &N) -> bool {
let mut a_parent = a.clone();
let mut b_parent = b.clone();
if !a_parent.move_to_parent() || !b_parent.move_to_parent() {
return false;
}
same_node(&a_parent, &b_parent)
}
#[cfg(test)]
mod tests {
}