#![deny(missing_docs)]
#[derive(Debug, PartialEq)]
pub enum Error {
Incomplete,
MultipleRoots,
}
#[derive(Debug, Clone, Copy)]
struct Vertex<T> {
len: usize,
data: T,
}
#[derive(Debug)]
pub struct Sapling<T> {
path: Vec<usize>,
verts: Vec<Vertex<T>>,
}
impl<T> Sapling<T> {
pub fn new() -> Self {
Sapling {
path: Vec::new(),
verts: Vec::new(),
}
}
pub fn with_capacity(len: usize, depth: Option<usize>) -> Self {
Sapling {
path: Vec::with_capacity(depth.unwrap_or(0)),
verts: Vec::with_capacity(len),
}
}
pub fn push(&mut self, data: T) {
self.path.push(self.verts.len());
self.verts.push(Vertex { len: 0, data });
}
pub fn push_leaf(&mut self, data: T) {
self.verts.push(Vertex { len: 0, data });
}
pub fn push_tree(&mut self, tree: Tree<T>) -> Sapling<T> {
let mut sap = tree.into_sapling();
self.verts.append(&mut sap.verts);
sap.clear();
sap
}
pub fn peek(&self) -> Option<&T> {
let i = *self.path.last()?;
Some(&self.verts[i].data)
}
pub fn pop(&mut self) -> Option<&T> {
let i = self.path.pop()?;
self.verts[i].len = self.verts.len() - i - 1;
Some(&self.verts[i].data)
}
pub fn pop_all(&mut self) {
while let Some(i) = self.path.pop() {
self.verts[i].len = self.verts.len() - i - 1;
}
}
pub fn pop_as_leaf(&mut self) -> Option<&T> {
let i = self.path.pop()?;
Some(&self.verts[i].data)
}
pub fn pop_as_leaf_all(&mut self) {
self.path.clear();
}
pub fn clear(&mut self) {
self.path.clear();
self.verts.clear();
}
pub fn is_empty(&self) -> bool {
self.verts.is_empty()
}
pub fn is_ready(&self) -> bool {
self.path.is_empty() && !self.verts.is_empty()
}
pub fn build(self) -> Result<Tree<T>, (Sapling<T>, Error)> {
if !self.is_ready() {
return Err((self, Error::Incomplete));
}
if self.verts[0].len < self.verts.len() - 1 {
return Err((self, Error::MultipleRoots));
}
Ok(Tree {
path: self.path,
verts: self.verts,
})
}
}
impl<T: Clone> Sapling<T> {
pub fn push_node(&mut self, node: Node<T>) {
self.verts.extend_from_slice(node.verts);
}
}
#[derive(Debug)]
pub struct Tree<T> {
path: Vec<usize>,
verts: Vec<Vertex<T>>,
}
impl<T> Tree<T> {
pub fn root(&self) -> Node<'_, T> {
Node {
depth: 0,
verts: &self.verts[..],
}
}
pub fn len(&self) -> usize {
self.verts.len()
}
pub fn into_sapling(self) -> Sapling<T> {
Sapling {
path: self.path,
verts: self.verts,
}
}
}
#[derive(Debug)]
pub struct Node<'a, T> {
depth: usize,
verts: &'a [Vertex<T>],
}
impl<'a, T> Node<'a, T> {
pub fn data(&self) -> &T {
&self.verts[0].data
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn len(&self) -> usize {
self.verts.len()
}
pub fn is_leaf(&self) -> bool {
self.verts.len() == 1
}
pub fn iter(&self) -> Descendants<'a, T> {
Descendants {
depth: self.depth,
verts: self.verts,
pos: 0,
}
}
pub fn children(&self) -> Children<'a, T> {
Children {
child_depth: self.depth + 1,
verts: &self.verts[1..],
}
}
}
impl<'a, T: Clone> Node<'a, T> {
pub fn into_tree(self) -> Tree<T> {
let mut verts = Vec::new();
verts.extend_from_slice(self.verts);
Tree {
path: Vec::new(),
verts,
}
}
}
#[derive(Debug)]
pub struct Descendants<'a, T> {
depth: usize,
verts: &'a [Vertex<T>],
pos: usize,
}
impl<'a, T> Iterator for Descendants<'a, T> {
type Item = Node<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
let verts = &self.verts[self.pos..self.pos + self.verts.get(self.pos)?.len + 1];
let mut depth = self.depth;
let mut i = 0;
while i < self.pos {
let len = self.verts[i].len;
if i + len < self.pos {
i += len + 1;
} else {
depth += 1;
i += 1;
}
}
self.pos += 1;
Some(Node { depth, verts })
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.verts.len(), Some(self.verts.len()))
}
fn count(self) -> usize {
self.verts.len()
}
}
#[derive(Debug)]
pub struct Children<'a, T> {
child_depth: usize,
verts: &'a [Vertex<T>],
}
impl<'a, T> Iterator for Children<'a, T> {
type Item = Node<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
let (verts, remainder) = &self.verts.split_at(self.verts.get(0)?.len + 1);
self.verts = remainder;
Some(Node {
depth: self.child_depth,
verts,
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.verts.is_empty() {
(0, Some(0))
} else {
(1, Some(self.verts.len()))
}
}
}