pub use self::tree_ref::Ref;
use std::ops::{Index, IndexMut};
pub mod tree_ref;
#[derive(Debug)]
pub struct Tree<T> {
nodes: Vec<Node<T>>,
}
impl<T> Default for Tree<T> {
fn default() -> Self {
Self { nodes: Default::default() }
}
}
impl<T> Tree<T> {
pub fn get(&self, index: Ref<T>) -> Option<&T> {
self.get_node(index).map(|node| &node.value)
}
pub fn get_mut(&mut self, index: Ref<T>) -> Option<&mut T> {
self.get_node_mut(index).map(|node| &mut node.value)
}
pub fn get_node(&self, index: Ref<T>) -> Option<&Node<T>> {
self.nodes.get(usize::from(index))
}
pub fn get_node_mut(&mut self, index: Ref<T>) -> Option<&mut Node<T>> {
self.nodes.get_mut(usize::from(index))
}
}
impl<T> Tree<T> {
pub fn new() -> Self {
Self { nodes: Default::default() }
}
pub fn root(&mut self, value: T) -> Result<Ref<T>, T> {
if self.is_empty() {
let node = Ref::new_unchecked(self.nodes.len());
self.nodes.push(Node::from(value));
Ok(node)
} else {
Err(value)
}
}
pub fn get_root(&mut self) -> Option<Ref<T>> {
match self.nodes.is_empty() {
true => None,
false => Some(Ref::new_unchecked(0)),
}
}
pub fn insert(&mut self, value: T, parent: Ref<T>) -> Ref<T> {
let child = Ref::new_unchecked(self.nodes.len());
self.nodes.push(Node::with_parent(value, parent));
self[parent].children.push(child);
child
}
pub fn depth(&self, node: Ref<T>) -> usize {
match self[node].parent {
Some(node) => self.depth(node) + 1,
None => 0,
}
}
pub fn branches(&self) -> usize {
self.nodes.iter().fold(0, |edges, node| edges + node.len())
}
}
impl<T> Tree<T> {
pub fn len(&self) -> usize {
self.nodes.len()
}
pub fn is_empty(&self) -> bool {
self.nodes.is_empty()
}
}
impl<T> Index<Ref<T>> for Tree<T> {
type Output = Node<T>;
fn index(&self, index: Ref<T>) -> &Self::Output {
self.get_node(index).expect("Ref should be inside Tree")
}
}
impl<T> IndexMut<Ref<T>> for Tree<T> {
fn index_mut(&mut self, index: Ref<T>) -> &mut Self::Output {
self.get_node_mut(index).expect("Ref should be inside Tree")
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Node<T> {
value: T,
parent: Option<Ref<T>>,
children: Vec<Ref<T>>,
}
impl<T> Node<T> {
pub const fn new(value: T) -> Self {
Self { value, parent: None, children: vec![] }
}
pub const fn with_parent(value: T, parent: Ref<T>) -> Self {
Self { value, parent: Some(parent), children: vec![] }
}
pub fn get(&self) -> &T {
self.as_ref()
}
pub fn get_mut(&mut self) -> &mut T {
self.as_mut()
}
pub fn swap(&mut self, value: T) -> T {
std::mem::replace(&mut self.value, value)
}
pub fn parent(&self) -> Option<Ref<T>> {
self.parent
}
pub fn children(&self) -> &[Ref<T>] {
&self.children
}
pub fn len(&self) -> usize {
self.children.len()
}
pub fn is_empty(&self) -> bool {
self.children.is_empty()
}
}
impl<T> AsRef<T> for Node<T> {
fn as_ref(&self) -> &T {
&self.value
}
}
impl<T> AsMut<T> for Node<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T> From<T> for Node<T> {
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
#[cfg(test)]
mod test {
#[allow(unused)]
use super::*;
#[test]
fn add_children() {
let mut tree = Tree::new();
let root = tree.root(0).unwrap();
let one = tree.insert(1, root);
let two = tree.insert(2, root);
assert_eq!([one, two].as_slice(), tree[root].children());
}
#[test]
fn nest_children() {
let mut tree = Tree::new();
let root = tree.root(0).unwrap();
let one = tree.insert(1, root);
let two = tree.insert(2, one);
assert_eq!(&[one], tree[root].children());
assert_eq!(&[two], tree[one].children());
assert_eq!(tree[two].children(), &[]);
}
#[test]
fn compares_equal() {}
}