use super::navigator_impl::Navigator;
use super::neighbors::Neighbors;
pub struct Builder {
parents_stack: Vec<usize>,
last_sibling: Option<usize>,
cur_neighbors: Vec<Neighbors<usize>>,
}
impl Default for Builder {
fn default() -> Builder {
Builder {
cur_neighbors: Vec::new(),
parents_stack: Vec::new(),
last_sibling: None,
}
}
}
impl Builder {
pub fn with_capacity(c: usize) -> Builder {
Builder {
cur_neighbors: Vec::with_capacity(c),
parents_stack: Vec::new(),
last_sibling: None,
}
}
pub fn start_element(&mut self) -> usize {
let my_index = self.cur_neighbors.len();
self.cur_neighbors.push(Neighbors {
me: Some(my_index),
parent: self.parents_stack.last().cloned(),
first_child: None,
next_sibling: None,
prev_sibling: self.last_sibling,
});
if let Some(ls) = self.last_sibling {
self.cur_neighbors[ls].next_sibling = Some(my_index);
}
if let Some(&parent_index) = self.parents_stack.last() {
if self.cur_neighbors[parent_index].first_child.is_none() {
self.cur_neighbors[parent_index].first_child = Some(my_index);
}
}
self.parents_stack.push(my_index);
self.last_sibling = None;
my_index
}
pub fn end_element(&mut self) -> usize {
self.last_sibling = self.parents_stack.pop();
self.last_sibling.unwrap()
}
pub fn start_end_element(&mut self) -> usize {
let my_index = self.cur_neighbors.len();
self.cur_neighbors.push(Neighbors {
me: Some(my_index),
first_child: None,
parent: self.parents_stack.last().cloned(),
next_sibling: None,
prev_sibling: self.last_sibling,
});
if let Some(ls) = self.last_sibling {
self.cur_neighbors[ls].next_sibling = Some(my_index);
}
if let Some(&parent_index) = self.parents_stack.last() {
if self.cur_neighbors[parent_index].first_child.is_none() {
self.cur_neighbors[parent_index].first_child = Some(my_index);
}
}
self.last_sibling = Some(my_index);
my_index
}
pub fn build(self) -> Navigator {
Navigator::new(self.cur_neighbors)
}
}