#![doc = include_str!("../README.md")]
mod iter;
mod node;
pub use iter::{IterBFS, IterDFS};
pub use node::{Node, NodeBuilder};
use std::{fmt::Debug, pin::Pin, ptr::NonNull};
type Owned<T> = Pin<Box<T>>;
type Parent<T> = NonNull<T>;
pub struct Tree<T> {
root: Owned<Node<T>>,
}
impl<T> Tree<T> {
#[inline]
pub fn builder(content: T) -> NodeBuilder<T> {
NodeBuilder::new(content)
}
pub fn root(&self) -> &Node<T> {
self.root.as_ref().get_ref()
}
pub fn root_mut(&mut self) -> Pin<&mut Node<T>> {
self.root.as_mut()
}
#[inline]
pub fn detach_descendant(&mut self, descendant: NonNull<Node<T>>) -> Option<Self> {
self.root_mut().detach_descendant(descendant)
}
#[inline]
pub fn borrow_descendant(&mut self, descendant: NonNull<Node<T>>) -> Option<Pin<&mut Node<T>>> {
self.root_mut().borrow_descendant(descendant)
}
#[inline]
pub fn iter_bfs(&self) -> IterBFS<T> {
IterBFS::new(self.root())
}
#[inline]
pub fn iter_dfs(&self) -> IterDFS<T> {
IterDFS::new(self.root())
}
}
impl<'a, T> IntoIterator for &'a Tree<T> {
type Item = &'a Node<T>;
type IntoIter = IterBFS<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_bfs()
}
}
impl<T> From<NodeBuilder<T>> for Tree<T> {
#[inline]
fn from(builder: NodeBuilder<T>) -> Self {
builder.build()
}
}
impl<T: Default> Default for Tree<T> {
fn default() -> Self {
NodeBuilder::default().build()
}
}
impl<T: Clone> Clone for Tree<T> {
fn clone(&self) -> Self {
self.root().clone_deep()
}
}
impl<T: PartialEq> PartialEq for Tree<T> {
fn eq(&self, other: &Self) -> bool {
self.root().eq(other.root())
}
}
impl<T: Eq> Eq for Tree<T> {}
impl<T: Debug> Debug for Tree<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Tree")
.field("root", &self.root().debug_tree())
.finish()
}
}
pub struct DebugTree<'a, T: Debug> {
root: &'a Node<T>,
}
impl<'a, T: Debug> Debug for DebugTree<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Node")
.field("content", &self.root.content)
.field(
"children",
&self
.root
.children()
.iter()
.map(|c| c.debug_tree())
.collect::<Box<_>>(),
)
.finish()
}
}