#![warn(
missing_docs,
missing_debug_implementations,
missing_copy_implementations
)]
use std::fmt::{self, Debug, Display, Formatter};
use std::num::NonZeroUsize;
#[cfg(feature = "serde")]
pub mod serde;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Tree<T> {
vec: Vec<Node<T>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NodeId(NonZeroUsize);
impl NodeId {
unsafe fn from_index(n: usize) -> Self {
NodeId(NonZeroUsize::new_unchecked(n + 1))
}
fn to_index(self) -> usize {
self.0.get() - 1
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Node<T> {
parent: Option<NodeId>,
prev_sibling: Option<NodeId>,
next_sibling: Option<NodeId>,
children: Option<(NodeId, NodeId)>,
value: T,
}
fn _static_assert_size_of_node() {
let _ = std::mem::transmute::<Node<()>, [usize; 5]>;
}
impl<T> Node<T> {
fn new(value: T) -> Self {
Node {
parent: None,
prev_sibling: None,
next_sibling: None,
children: None,
value,
}
}
}
#[derive(Debug)]
pub struct NodeRef<'a, T: 'a> {
id: NodeId,
tree: &'a Tree<T>,
node: &'a Node<T>,
}
#[derive(Debug)]
pub struct NodeMut<'a, T: 'a> {
id: NodeId,
tree: &'a mut Tree<T>,
}
impl<'a, T: 'a> Copy for NodeRef<'a, T> {}
impl<'a, T: 'a> Clone for NodeRef<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T: 'a> Eq for NodeRef<'a, T> {}
impl<'a, T: 'a> PartialEq for NodeRef<'a, T> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& std::ptr::eq(self.tree, other.tree)
&& std::ptr::eq(self.node, other.node)
}
}
impl<T> Tree<T> {
pub fn new(root: T) -> Self {
Tree {
vec: vec![Node::new(root)],
}
}
pub fn with_capacity(root: T, capacity: usize) -> Self {
let mut vec = Vec::with_capacity(capacity);
vec.push(Node::new(root));
Tree { vec }
}
pub fn get(&self, id: NodeId) -> Option<NodeRef<T>> {
self.vec.get(id.to_index()).map(|node| NodeRef {
id,
node,
tree: self,
})
}
pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<T>> {
let exists = self.vec.get(id.to_index()).map(|_| ());
exists.map(move |_| NodeMut { id, tree: self })
}
unsafe fn node(&self, id: NodeId) -> &Node<T> {
self.vec.get_unchecked(id.to_index())
}
unsafe fn node_mut(&mut self, id: NodeId) -> &mut Node<T> {
self.vec.get_unchecked_mut(id.to_index())
}
pub unsafe fn get_unchecked(&self, id: NodeId) -> NodeRef<T> {
NodeRef {
id,
node: self.node(id),
tree: self,
}
}
pub unsafe fn get_unchecked_mut(&mut self, id: NodeId) -> NodeMut<T> {
NodeMut { id, tree: self }
}
pub fn root(&self) -> NodeRef<T> {
unsafe { self.get_unchecked(NodeId::from_index(0)) }
}
pub fn root_mut(&mut self) -> NodeMut<T> {
unsafe { self.get_unchecked_mut(NodeId::from_index(0)) }
}
pub fn orphan(&mut self, value: T) -> NodeMut<T> {
let id = unsafe { NodeId::from_index(self.vec.len()) };
self.vec.push(Node::new(value));
unsafe { self.get_unchecked_mut(id) }
}
#[allow(clippy::option_map_unit_fn)]
pub fn extend_tree(&mut self, mut other_tree: Tree<T>) -> NodeMut<T> {
let offset = self.vec.len();
let offset_id = |id: NodeId| -> NodeId {
let old_index = id.to_index();
let new_index = old_index + offset;
unsafe { NodeId::from_index(new_index) }
};
let other_tree_root_id = offset_id(other_tree.root().id);
for node in other_tree.vec.iter_mut() {
node.parent.as_mut().map(|id| *id = offset_id(*id));
node.prev_sibling.as_mut().map(|id| *id = offset_id(*id));
node.next_sibling.as_mut().map(|id| *id = offset_id(*id));
node.children.as_mut().map(|(id1, id2)| {
*id1 = offset_id(*id1);
*id2 = offset_id(*id2);
});
}
self.vec.extend(other_tree.vec);
unsafe { self.get_unchecked_mut(other_tree_root_id) }
}
}
impl<'a, T: 'a> NodeRef<'a, T> {
pub fn id(&self) -> NodeId {
self.id
}
pub fn tree(&self) -> &'a Tree<T> {
self.tree
}
pub fn value(&self) -> &'a T {
&self.node.value
}
fn axis<F>(&self, f: F) -> Option<Self>
where
F: FnOnce(&Node<T>) -> Option<NodeId>,
{
f(self.node).map(|id| unsafe { self.tree.get_unchecked(id) })
}
pub fn parent(&self) -> Option<Self> {
self.axis(|node| node.parent)
}
pub fn prev_sibling(&self) -> Option<Self> {
self.axis(|node| node.prev_sibling)
}
pub fn next_sibling(&self) -> Option<Self> {
self.axis(|node| node.next_sibling)
}
pub fn first_child(&self) -> Option<Self> {
self.axis(|node| node.children.map(|(id, _)| id))
}
pub fn last_child(&self) -> Option<Self> {
self.axis(|node| node.children.map(|(_, id)| id))
}
pub fn has_siblings(&self) -> bool {
self.node.prev_sibling.is_some() || self.node.next_sibling.is_some()
}
pub fn has_children(&self) -> bool {
self.node.children.is_some()
}
}
impl<'a, T: 'a> NodeMut<'a, T> {
pub fn id(&self) -> NodeId {
self.id
}
pub fn tree(&mut self) -> &mut Tree<T> {
self.tree
}
fn node(&mut self) -> &mut Node<T> {
unsafe { self.tree.node_mut(self.id) }
}
pub fn value(&mut self) -> &mut T {
&mut self.node().value
}
fn axis<F>(&mut self, f: F) -> Option<NodeMut<T>>
where
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
{
let id = f(self.node());
id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) })
}
fn into_axis<F>(mut self, f: F) -> Result<Self, Self>
where
F: FnOnce(&mut Node<T>) -> Option<NodeId>,
{
let id = f(self.node());
match id {
Some(id) => Ok(unsafe { self.tree.get_unchecked_mut(id) }),
None => Err(self),
}
}
pub fn parent(&mut self) -> Option<NodeMut<T>> {
self.axis(|node| node.parent)
}
pub fn into_parent(self) -> Result<Self, Self> {
self.into_axis(|node| node.parent)
}
pub fn prev_sibling(&mut self) -> Option<NodeMut<T>> {
self.axis(|node| node.prev_sibling)
}
pub fn into_prev_sibling(self) -> Result<Self, Self> {
self.into_axis(|node| node.prev_sibling)
}
pub fn next_sibling(&mut self) -> Option<NodeMut<T>> {
self.axis(|node| node.next_sibling)
}
pub fn into_next_sibling(self) -> Result<Self, Self> {
self.into_axis(|node| node.next_sibling)
}
pub fn first_child(&mut self) -> Option<NodeMut<T>> {
self.axis(|node| node.children.map(|(id, _)| id))
}
pub fn into_first_child(self) -> Result<Self, Self> {
self.into_axis(|node| node.children.map(|(id, _)| id))
}
pub fn last_child(&mut self) -> Option<NodeMut<T>> {
self.axis(|node| node.children.map(|(_, id)| id))
}
pub fn into_last_child(self) -> Result<Self, Self> {
self.into_axis(|node| node.children.map(|(_, id)| id))
}
pub fn has_siblings(&self) -> bool {
unsafe { self.tree.get_unchecked(self.id).has_siblings() }
}
pub fn has_children(&self) -> bool {
unsafe { self.tree.get_unchecked(self.id).has_children() }
}
pub fn append(&mut self, value: T) -> NodeMut<T> {
let id = self.tree.orphan(value).id;
self.append_id(id)
}
pub fn prepend(&mut self, value: T) -> NodeMut<T> {
let id = self.tree.orphan(value).id;
self.prepend_id(id)
}
pub fn append_subtree(&mut self, subtree: Tree<T>) -> NodeMut<T> {
let root_id = self.tree.extend_tree(subtree).id;
self.append_id(root_id)
}
pub fn prepend_subtree(&mut self, subtree: Tree<T>) -> NodeMut<T> {
let root_id = self.tree.extend_tree(subtree).id;
self.prepend_id(root_id)
}
pub fn insert_before(&mut self, value: T) -> NodeMut<T> {
let id = self.tree.orphan(value).id;
self.insert_id_before(id)
}
pub fn insert_after(&mut self, value: T) -> NodeMut<T> {
let id = self.tree.orphan(value).id;
self.insert_id_after(id)
}
pub fn detach(&mut self) {
let parent_id = match self.node().parent {
Some(id) => id,
None => return,
};
let prev_sibling_id = self.node().prev_sibling;
let next_sibling_id = self.node().next_sibling;
{
self.node().parent = None;
self.node().prev_sibling = None;
self.node().next_sibling = None;
}
if let Some(id) = prev_sibling_id {
unsafe {
self.tree.node_mut(id).next_sibling = next_sibling_id;
}
}
if let Some(id) = next_sibling_id {
unsafe {
self.tree.node_mut(id).prev_sibling = prev_sibling_id;
}
}
let parent = unsafe { self.tree.node_mut(parent_id) };
let (first_child_id, last_child_id) = parent.children.unwrap();
if first_child_id == last_child_id {
parent.children = None;
} else if first_child_id == self.id {
parent.children = Some((next_sibling_id.unwrap(), last_child_id));
} else if last_child_id == self.id {
parent.children = Some((first_child_id, prev_sibling_id.unwrap()));
}
}
pub fn append_id(&mut self, new_child_id: NodeId) -> NodeMut<T> {
let last_child_id = self.node().children.map(|(_, id)| id);
{
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
new_child.detach();
new_child.node().parent = Some(self.id);
new_child.node().prev_sibling = last_child_id;
}
if let Some(id) = last_child_id {
unsafe {
self.tree.node_mut(id).next_sibling = Some(new_child_id);
}
}
{
if let Some((first_child_id, _)) = self.node().children {
self.node().children = Some((first_child_id, new_child_id));
} else {
self.node().children = Some((new_child_id, new_child_id));
}
}
unsafe { self.tree.get_unchecked_mut(new_child_id) }
}
pub fn prepend_id(&mut self, new_child_id: NodeId) -> NodeMut<T> {
let first_child_id = self.node().children.map(|(id, _)| id);
{
let mut new_child = self.tree.get_mut(new_child_id).unwrap();
new_child.detach();
new_child.node().parent = Some(self.id);
new_child.node().next_sibling = first_child_id;
}
if let Some(id) = first_child_id {
unsafe {
self.tree.node_mut(id).prev_sibling = Some(new_child_id);
}
}
{
if let Some((_, last_child_id)) = self.node().children {
self.node().children = Some((new_child_id, last_child_id));
} else {
self.node().children = Some((new_child_id, new_child_id));
}
}
unsafe { self.tree.get_unchecked_mut(new_child_id) }
}
pub fn insert_id_before(&mut self, new_sibling_id: NodeId) -> NodeMut<T> {
let parent_id = self.node().parent.unwrap();
let prev_sibling_id = self.node().prev_sibling;
{
let mut new_sibling = self.tree.get_mut(new_sibling_id).unwrap();
new_sibling.detach();
new_sibling.node().parent = Some(parent_id);
new_sibling.node().prev_sibling = prev_sibling_id;
new_sibling.node().next_sibling = Some(self.id);
}
if let Some(id) = prev_sibling_id {
unsafe {
self.tree.node_mut(id).next_sibling = Some(new_sibling_id);
}
}
self.node().prev_sibling = Some(new_sibling_id);
{
let parent = unsafe { self.tree.node_mut(parent_id) };
let (first_child_id, last_child_id) = parent.children.unwrap();
if first_child_id == self.id {
parent.children = Some((new_sibling_id, last_child_id));
}
}
unsafe { self.tree.get_unchecked_mut(new_sibling_id) }
}
pub fn insert_id_after(&mut self, new_sibling_id: NodeId) -> NodeMut<T> {
let parent_id = self.node().parent.unwrap();
let next_sibling_id = self.node().next_sibling;
{
let mut new_sibling = self.tree.get_mut(new_sibling_id).unwrap();
new_sibling.detach();
new_sibling.node().parent = Some(parent_id);
new_sibling.node().prev_sibling = Some(self.id);
new_sibling.node().next_sibling = next_sibling_id;
}
if let Some(id) = next_sibling_id {
unsafe {
self.tree.node_mut(id).prev_sibling = Some(new_sibling_id);
}
}
self.node().next_sibling = Some(new_sibling_id);
{
let parent = unsafe { self.tree.node_mut(parent_id) };
let (first_child_id, last_child_id) = parent.children.unwrap();
if last_child_id == self.id {
parent.children = Some((first_child_id, new_sibling_id));
}
}
unsafe { self.tree.get_unchecked_mut(new_sibling_id) }
}
pub fn reparent_from_id_append(&mut self, from_id: NodeId) {
let new_child_ids = {
let mut from = self.tree.get_mut(from_id).unwrap();
match from.node().children.take() {
Some(ids) => ids,
None => return,
}
};
unsafe {
self.tree.node_mut(new_child_ids.0).parent = Some(self.id);
self.tree.node_mut(new_child_ids.1).parent = Some(self.id);
}
if self.node().children.is_none() {
self.node().children = Some(new_child_ids);
return;
}
let old_child_ids = self.node().children.unwrap();
unsafe {
self.tree.node_mut(old_child_ids.1).next_sibling = Some(new_child_ids.0);
self.tree.node_mut(new_child_ids.0).prev_sibling = Some(old_child_ids.1);
}
self.node().children = Some((old_child_ids.0, new_child_ids.1));
}
pub fn reparent_from_id_prepend(&mut self, from_id: NodeId) {
let new_child_ids = {
let mut from = self.tree.get_mut(from_id).unwrap();
match from.node().children.take() {
Some(ids) => ids,
None => return,
}
};
unsafe {
self.tree.node_mut(new_child_ids.0).parent = Some(self.id);
self.tree.node_mut(new_child_ids.1).parent = Some(self.id);
}
if self.node().children.is_none() {
self.node().children = Some(new_child_ids);
return;
}
let old_child_ids = self.node().children.unwrap();
unsafe {
self.tree.node_mut(old_child_ids.0).prev_sibling = Some(new_child_ids.1);
self.tree.node_mut(new_child_ids.1).next_sibling = Some(old_child_ids.0);
}
self.node().children = Some((new_child_ids.0, old_child_ids.1));
}
}
impl<'a, T: 'a> From<NodeMut<'a, T>> for NodeRef<'a, T> {
fn from(node: NodeMut<'a, T>) -> Self {
unsafe { node.tree.get_unchecked(node.id) }
}
}
pub mod iter;
#[macro_export]
macro_rules! tree {
(@ $n:ident { }) => { };
(@ $n:ident { $value:expr }) => {
{ $n.append($value); }
};
(@ $n:ident { $value:expr, $($tail:tt)* }) => {
{
$n.append($value);
tree!(@ $n { $($tail)* });
}
};
(@ $n:ident { $value:expr => $children:tt }) => {
{
let mut node = $n.append($value);
tree!(@ node $children);
}
};
(@ $n:ident { $value:expr => $children:tt, $($tail:tt)* }) => {
{
{
let mut node = $n.append($value);
tree!(@ node $children);
}
tree!(@ $n { $($tail)* });
}
};
($root:expr) => { $crate::Tree::new($root) };
($root:expr => $children:tt) => {
{
let mut tree = $crate::Tree::new($root);
{
let mut node = tree.root_mut();
tree!(@ node $children);
}
tree
}
};
}
impl<T: Debug> Debug for Tree<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
use crate::iter::Edge;
if f.alternate() {
write!(f, "Tree {{")?;
for edge in self.root().traverse() {
match edge {
Edge::Open(node) if node.has_children() => {
write!(f, " {:?} => {{", node.value())?;
}
Edge::Open(node) if node.next_sibling().is_some() => {
write!(f, " {:?},", node.value())?;
}
Edge::Open(node) => {
write!(f, " {:?}", node.value())?;
}
Edge::Close(node) if node.has_children() => {
if node.next_sibling().is_some() {
write!(f, " }},")?;
} else {
write!(f, " }}")?;
}
}
_ => {}
}
}
write!(f, " }}")
} else {
f.debug_struct("Tree").field("vec", &self.vec).finish()
}
}
}
mod display;
impl<T: Display> Display for Tree<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
use crate::display::Indentation;
use crate::iter::Edge;
let mut indent: Indentation = Indentation::new(true);
for edge in self.root().traverse() {
match edge {
Edge::Open(node) if node.has_children() => {
indent.indent(node.next_sibling().is_some());
writeln!(f, "{indent}{}", node.value())?;
}
Edge::Open(node) => {
indent.indent(node.next_sibling().is_some());
writeln!(f, "{indent}{}", node.value())?;
indent.deindent();
}
Edge::Close(node) if node.has_children() => {
indent.deindent();
}
_ => {}
}
}
Ok(())
}
}