#![warn(missing_docs)]
use std::sync::Arc;
#[cfg(test)]
mod tests;
#[derive(Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct PathTree<T>(Arc<PathTreeInner<T>>);
impl<T> Clone for PathTree<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(Debug, Default, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
struct PathTreeInner<T> {
segment: Option<T>,
parent: Option<PathTree<T>>,
child: Option<PathTree<T>>,
}
impl<T> PathTree<T> {
fn node(segment: Option<T>, parent: Option<PathTree<T>>, child: Option<PathTree<T>>) -> Self {
PathTree(Arc::new(PathTreeInner {
segment,
parent,
child,
}))
}
fn segment(&self) -> &Option<T> {
&self.0.segment
}
fn parent(&self) -> &Option<Self> {
&self.0.parent
}
fn child(&self) -> &Option<Self> {
&self.0.child
}
pub fn new(segment: T) -> Self {
Self::node(Some(segment), None, None)
}
pub fn empty() -> Self {
Self::node(None, None, None)
}
pub fn append(&self, other: &PathTree<T>) -> Self {
Self::node(None, Some((*self).clone()), Some((*other).clone()))
}
pub fn prepend(&self, other: &PathTree<T>) -> Self {
other.append(self)
}
pub fn append_segment(&self, segment: T) -> Self {
Self::node(Some(segment), Some((*self).clone()), None)
}
pub fn prepend_segment(&self, segment: T) -> Self {
Self::node(Some(segment), None, Some((*self).clone()))
}
pub fn iter(&self) -> Iter<'_, T> {
let mut iter = Iter::new();
iter.push_node_and_parents(self);
iter
}
}
impl<'a, T> IntoIterator for &'a PathTree<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<A> FromIterator<A> for PathTree<A> {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
let mut iter = iter.into_iter();
if let Some(elem) = iter.next() {
let mut tree = PathTree::new(elem);
for elem in iter {
tree = tree.append_segment(elem);
}
tree
} else {
PathTree::empty()
}
}
}
pub struct Iter<'a, T> {
stack: Vec<&'a PathTree<T>>,
}
impl<'a, T> Iter<'a, T> {
fn new() -> Self {
Self { stack: Vec::new() }
}
fn push_node_and_parents(&mut self, node: &'a PathTree<T>) {
let mut parent = Some(node);
while let Some(curr) = parent {
self.stack.push(curr);
parent = curr.parent().as_ref();
}
}
fn push_child(&mut self, node: &'a PathTree<T>) {
if let Some(child) = node.child() {
self.push_node_and_parents(child);
}
}
fn pop(&mut self) -> Option<&'a PathTree<T>> {
let top = self.stack.pop();
if let Some(top) = top {
self.push_child(top);
}
top
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.pop() {
if let Some(segment) = next.segment().as_ref() {
return Some(segment);
}
}
None
}
}