use std::{ops::Deref, rc::Rc};
use super::Node;
#[derive(Debug)]
pub struct Children<'a> {
front: Option<Rc<Node<'a>>>,
back: Option<Rc<Node<'a>>>,
}
impl<'a> Clone for Children<'a> {
fn clone(&self) -> Self {
Self {
front: self.front.clone(),
back: self.back.clone(),
}
}
}
impl<'a> Iterator for Children<'a> {
type Item = Rc<Node<'a>>;
fn next(&mut self) -> Option<Self::Item> {
if self.front == self.back {
let node = self.front.take();
self.back = None;
node
} else {
let node = self.front.take();
self.front = node.as_deref().and_then(Node::next_sibling);
node
}
}
}
#[derive(Debug, Clone)]
pub enum Edge<'a> {
Open(Rc<Node<'a>>),
Close(Rc<Node<'a>>),
}
impl<'a> Eq for Edge<'a> {}
impl<'a> PartialEq for Edge<'a> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Edge::Open(a), Edge::Open(b)) | (Edge::Close(a), Edge::Close(b)) => a == b,
_ => false,
}
}
}
#[derive(Debug, Clone)]
pub struct Traverse<'a> {
root: Option<Rc<Node<'a>>>,
edge: Option<Edge<'a>>,
}
impl<'a> Iterator for Traverse<'a> {
type Item = Edge<'a>;
fn next(&mut self) -> Option<Self::Item> {
match &self.edge {
None => {
if let Some(root) = &self.root {
self.edge = Some(Edge::Open(root.clone()));
}
}
Some(Edge::Open(node)) => {
if let Some(first_child) = node.first_child() {
self.edge = Some(Edge::Open(first_child));
} else {
self.edge = Some(Edge::Close(node.clone()));
}
}
Some(Edge::Close(node)) => {
if *node == self.root.clone().unwrap() {
self.root = None;
self.edge = None;
} else if let Some(next_sibling) = node.next_sibling() {
self.edge = Some(Edge::Open(next_sibling));
} else {
self.edge = node.parent().map(Edge::Close);
}
}
}
self.edge.clone()
}
}
#[derive(Debug)]
pub struct Descendants<'a>(Traverse<'a>);
impl<'a> Clone for Descendants<'a> {
fn clone(&self) -> Self {
Descendants(self.0.clone())
}
}
impl<'a> Iterator for Descendants<'a> {
type Item = Rc<Node<'a>>;
fn next(&mut self) -> Option<Self::Item> {
for edge in &mut self.0 {
if let Edge::Open(node) = edge {
return Some(node);
}
}
None
}
}
macro_rules! axis_iterators {
($(#[$m:meta] $i:ident($f:path);)*) => {
$(
#[$m]
#[derive(Debug)]
pub struct $i<'a>(Option<Rc<Node<'a>>>);
impl<'a> Clone for $i<'a> {
fn clone(&self) -> Self {
$i(self.0.clone())
}
}
impl<'a> Iterator for $i<'a> {
type Item = Rc<Node<'a>>;
fn next(&mut self) -> Option<Self::Item> {
let node = self.0.take();
self.0 = node.as_ref().map(|x| x.deref()).and_then($f);
node
}
}
)*
};
}
axis_iterators! {
Ancestors(Node::parent);
PrevSiblings(Node::prev_sibling);
NextSiblings(Node::next_sibling);
FirstChildren(Node::first_child);
LastChildren(Node::last_child);
}
impl<'a> Node<'a> {
pub fn children(&self) -> Children<'a> {
Children {
front: self.first_child(),
back: self.last_child(),
}
}
pub fn traverse(self: &Rc<Node<'a>>) -> Traverse<'a> {
Traverse {
root: Some(self.clone()),
edge: None,
}
}
pub fn descendants(self: &Rc<Node<'a>>) -> Descendants<'a> {
Descendants(self.traverse())
}
pub fn ancestors(self: &Rc<Node<'a>>) -> Ancestors<'a> {
Ancestors(Some(self.clone()))
}
}