diff --git a/src/iter.rs b/src/iter.rs index fe591ef..72a01d1 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -2,14 +2,14 @@ use std::iter::FusedIterator; use std::ops::Range; use std::{slice, vec}; -use crate::{Node, NodeId, NodeRef, Tree}; +use crate::{ID, Node, NodeId, NodeRef, Tree}; /// Iterator that moves out of a tree in insert order. #[derive(Debug)] -pub struct IntoIter(vec::IntoIter>); -impl ExactSizeIterator for IntoIter {} -impl FusedIterator for IntoIter {} -impl Iterator for IntoIter { +pub struct IntoIter(vec::IntoIter>); +impl ExactSizeIterator for IntoIter {} +impl FusedIterator for IntoIter {} +impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { self.0.next().map(|node| node.value) @@ -18,7 +18,7 @@ impl Iterator for IntoIter { self.0.size_hint() } } -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.0.next_back().map(|node| node.value) } @@ -26,15 +26,15 @@ impl DoubleEndedIterator for IntoIter { /// Iterator over values in insert order. #[derive(Debug)] -pub struct Values<'a, T: 'a>(slice::Iter<'a, Node>); -impl<'a, T: 'a> Clone for Values<'a, T> { +pub struct Values<'a, T: 'a, I: ID = NodeId>(slice::Iter<'a, Node>); +impl<'a, T: 'a, I: ID> Clone for Values<'a, T, I> { fn clone(&self) -> Self { Values(self.0.clone()) } } -impl<'a, T: 'a> ExactSizeIterator for Values<'a, T> {} -impl<'a, T: 'a> FusedIterator for Values<'a, T> {} -impl<'a, T: 'a> Iterator for Values<'a, T> { +impl<'a, T: 'a, I: ID> ExactSizeIterator for Values<'a, T, I> {} +impl<'a, T: 'a, I: ID> FusedIterator for Values<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for Values<'a, T, I> { type Item = &'a T; fn next(&mut self) -> Option { self.0.next().map(|node| &node.value) @@ -43,7 +43,7 @@ impl<'a, T: 'a> Iterator for Values<'a, T> { self.0.size_hint() } } -impl<'a, T: 'a> DoubleEndedIterator for Values<'a, T> { +impl<'a, T: 'a, I: ID> DoubleEndedIterator for Values<'a, T, I> { fn next_back(&mut self) -> Option { self.0.next_back().map(|node| &node.value) } @@ -51,10 +51,10 @@ impl<'a, T: 'a> DoubleEndedIterator for Values<'a, T> { /// Mutable iterator over values in insert order. #[derive(Debug)] -pub struct ValuesMut<'a, T: 'a>(slice::IterMut<'a, Node>); -impl<'a, T: 'a> ExactSizeIterator for ValuesMut<'a, T> {} -impl<'a, T: 'a> FusedIterator for ValuesMut<'a, T> {} -impl<'a, T: 'a> Iterator for ValuesMut<'a, T> { +pub struct ValuesMut<'a, T: 'a, I: ID = NodeId>(slice::IterMut<'a, Node>); +impl<'a, T: 'a, I: ID> ExactSizeIterator for ValuesMut<'a, T, I> {} +impl<'a, T: 'a, I: ID> FusedIterator for ValuesMut<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for ValuesMut<'a, T, I> { type Item = &'a mut T; fn next(&mut self) -> Option { self.0.next().map(|node| &mut node.value) @@ -63,7 +63,7 @@ impl<'a, T: 'a> Iterator for ValuesMut<'a, T> { self.0.size_hint() } } -impl<'a, T: 'a> DoubleEndedIterator for ValuesMut<'a, T> { +impl<'a, T: 'a, I: ID> DoubleEndedIterator for ValuesMut<'a, T, I> { fn next_back(&mut self) -> Option { self.0.next_back().map(|node| &mut node.value) } @@ -71,11 +71,11 @@ impl<'a, T: 'a> DoubleEndedIterator for ValuesMut<'a, T> { /// Iterator over nodes in insert order. #[derive(Debug)] -pub struct Nodes<'a, T: 'a> { - tree: &'a Tree, +pub struct Nodes<'a, T: 'a, I: ID = NodeId> { + tree: &'a Tree, iter: Range, } -impl<'a, T: 'a> Clone for Nodes<'a, T> { +impl<'a, T: 'a, I: ID> Clone for Nodes<'a, T, I> { fn clone(&self) -> Self { Self { tree: self.tree, @@ -83,48 +83,48 @@ impl<'a, T: 'a> Clone for Nodes<'a, T> { } } } -impl<'a, T: 'a> ExactSizeIterator for Nodes<'a, T> {} -impl<'a, T: 'a> FusedIterator for Nodes<'a, T> {} -impl<'a, T: 'a> Iterator for Nodes<'a, T> { - type Item = NodeRef<'a, T>; +impl<'a, T: 'a, I: ID> ExactSizeIterator for Nodes<'a, T, I> {} +impl<'a, T: 'a, I: ID> FusedIterator for Nodes<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for Nodes<'a, T, I> { + type Item = NodeRef<'a, T, I>; fn next(&mut self) -> Option { self.iter .next() - .map(|i| unsafe { self.tree.get_unchecked(NodeId::from_index(i)) }) + .map(|i| unsafe { self.tree.get_unchecked(I::from_index(i)) }) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } -impl<'a, T: 'a> DoubleEndedIterator for Nodes<'a, T> { +impl<'a, T: 'a, I: ID> DoubleEndedIterator for Nodes<'a, T, I> { fn next_back(&mut self) -> Option { self.iter .next_back() - .map(|i| unsafe { self.tree.get_unchecked(NodeId::from_index(i)) }) + .map(|i| unsafe { self.tree.get_unchecked(I::from_index(i)) }) } } -impl IntoIterator for Tree { +impl IntoIterator for Tree { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter(self.vec.into_iter()) } } -impl Tree { +impl Tree { /// Returns an iterator over values in insert order. - pub fn values(&self) -> Values<'_, T> { + pub fn values(&self) -> Values<'_, T, I> { Values(self.vec.iter()) } /// Returns a mutable iterator over values in insert order. - pub fn values_mut(&mut self) -> ValuesMut<'_, T> { + pub fn values_mut(&mut self) -> ValuesMut<'_, T, I> { ValuesMut(self.vec.iter_mut()) } /// Returns an iterator over nodes in insert order. - pub fn nodes(&self) -> Nodes<'_, T> { + pub fn nodes(&self) -> Nodes<'_, T, I> { Nodes { tree: self, iter: 0..self.vec.len(), @@ -137,15 +137,15 @@ macro_rules! axis_iterators { $( #[$m] #[derive(Debug)] - pub struct $i<'a, T: 'a>(Option>); - impl<'a, T: 'a> Clone for $i<'a, T> { + pub struct $i<'a, T: 'a, I: ID = NodeId>(Option>); + impl<'a, T: 'a, I: ID> Clone for $i<'a, T, I> { fn clone(&self) -> Self { $i(self.0) } } - impl<'a, T: 'a> FusedIterator for $i<'a, T> {} - impl<'a, T: 'a> Iterator for $i<'a, T> { - type Item = NodeRef<'a, T>; + impl<'a, T: 'a, I: ID> FusedIterator for $i<'a, T, I> {} + impl<'a, T: 'a, I: ID> Iterator for $i<'a, T, I> { + type Item = NodeRef<'a, T, I>; fn next(&mut self) -> Option { let node = self.0.take(); self.0 = node.as_ref().and_then($f); @@ -175,11 +175,11 @@ axis_iterators! { /// Iterator over children. #[derive(Debug)] -pub struct Children<'a, T: 'a> { - front: Option>, - back: Option>, +pub struct Children<'a, T: 'a, I: ID = NodeId> { + front: Option>, + back: Option>, } -impl<'a, T: 'a> Clone for Children<'a, T> { +impl<'a, T: 'a, I: ID> Clone for Children<'a, T, I> { fn clone(&self) -> Self { Self { front: self.front, @@ -187,9 +187,9 @@ impl<'a, T: 'a> Clone for Children<'a, T> { } } } -impl<'a, T: 'a> FusedIterator for Children<'a, T> {} -impl<'a, T: 'a> Iterator for Children<'a, T> { - type Item = NodeRef<'a, T>; +impl<'a, T: 'a, I: ID> FusedIterator for Children<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for Children<'a, T, I> { + type Item = NodeRef<'a, T, I>; fn next(&mut self) -> Option { if self.front == self.back { let node = self.front.take(); @@ -202,7 +202,7 @@ impl<'a, T: 'a> Iterator for Children<'a, T> { } } } -impl<'a, T: 'a> DoubleEndedIterator for Children<'a, T> { +impl<'a, T: 'a, I: ID> DoubleEndedIterator for Children<'a, T, I> { fn next_back(&mut self) -> Option { if self.back == self.front { let node = self.back.take(); @@ -218,20 +218,20 @@ impl<'a, T: 'a> DoubleEndedIterator for Children<'a, T> { /// Open or close edge of a node. #[derive(Debug)] -pub enum Edge<'a, T: 'a> { +pub enum Edge<'a, T: 'a, I: ID> { /// Open. - Open(NodeRef<'a, T>), + Open(NodeRef<'a, T, I>), /// Close. - Close(NodeRef<'a, T>), + Close(NodeRef<'a, T, I>), } -impl<'a, T: 'a> Copy for Edge<'a, T> {} -impl<'a, T: 'a> Clone for Edge<'a, T> { +impl<'a, T: 'a, I: ID> Copy for Edge<'a, T, I> {} +impl<'a, T: 'a, I: ID> Clone for Edge<'a, T, I> { fn clone(&self) -> Self { *self } } -impl<'a, T: 'a> Eq for Edge<'a, T> {} -impl<'a, T: 'a> PartialEq for Edge<'a, T> { +impl<'a, T: 'a, I: ID> Eq for Edge<'a, T, I> {} +impl<'a, T: 'a, I: ID> PartialEq for Edge<'a, T, I> { fn eq(&self, other: &Self) -> bool { match (*self, *other) { (Edge::Open(a), Edge::Open(b)) | (Edge::Close(a), Edge::Close(b)) => a == b, @@ -242,11 +242,11 @@ impl<'a, T: 'a> PartialEq for Edge<'a, T> { /// Iterator which traverses a subtree. #[derive(Debug)] -pub struct Traverse<'a, T: 'a> { - root: Option>, - edge: Option>, +pub struct Traverse<'a, T: 'a, I: ID = NodeId> { + root: Option>, + edge: Option>, } -impl<'a, T: 'a> Clone for Traverse<'a, T> { +impl<'a, T: 'a, I: ID> Clone for Traverse<'a, T, I> { fn clone(&self) -> Self { Self { root: self.root, @@ -254,9 +254,9 @@ impl<'a, T: 'a> Clone for Traverse<'a, T> { } } } -impl<'a, T: 'a> FusedIterator for Traverse<'a, T> {} -impl<'a, T: 'a> Iterator for Traverse<'a, T> { - type Item = Edge<'a, T>; +impl<'a, T: 'a, I: ID> FusedIterator for Traverse<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for Traverse<'a, T, I> { + type Item = Edge<'a, T, I>; fn next(&mut self) -> Option { match self.edge { None => { @@ -288,15 +288,15 @@ impl<'a, T: 'a> Iterator for Traverse<'a, T> { /// Iterator over a node and its descendants. #[derive(Debug)] -pub struct Descendants<'a, T: 'a>(Traverse<'a, T>); -impl<'a, T: 'a> Clone for Descendants<'a, T> { +pub struct Descendants<'a, T: 'a, I: ID = NodeId>(Traverse<'a, T, I>); +impl<'a, T: 'a, I: ID> Clone for Descendants<'a, T, I> { fn clone(&self) -> Self { Descendants(self.0.clone()) } } -impl<'a, T: 'a> FusedIterator for Descendants<'a, T> {} -impl<'a, T: 'a> Iterator for Descendants<'a, T> { - type Item = NodeRef<'a, T>; +impl<'a, T: 'a, I: ID> FusedIterator for Descendants<'a, T, I> {} +impl<'a, T: 'a, I: ID> Iterator for Descendants<'a, T, I> { + type Item = NodeRef<'a, T, I>; fn next(&mut self) -> Option { for edge in &mut self.0 { if let Edge::Open(node) = edge { @@ -307,34 +307,34 @@ impl<'a, T: 'a> Iterator for Descendants<'a, T> { } } -impl<'a, T: 'a> NodeRef<'a, T> { +impl<'a, T: 'a, I: ID> NodeRef<'a, T, I> { /// Returns an iterator over ancestors. - pub fn ancestors(&self) -> Ancestors<'a, T> { + pub fn ancestors(&self) -> Ancestors<'a, T, I> { Ancestors(self.parent()) } /// Returns an iterator over previous siblings. - pub fn prev_siblings(&self) -> PrevSiblings<'a, T> { + pub fn prev_siblings(&self) -> PrevSiblings<'a, T, I> { PrevSiblings(self.prev_sibling()) } /// Returns an iterator over next siblings. - pub fn next_siblings(&self) -> NextSiblings<'a, T> { + pub fn next_siblings(&self) -> NextSiblings<'a, T, I> { NextSiblings(self.next_sibling()) } /// Returns an iterator over first children. - pub fn first_children(&self) -> FirstChildren<'a, T> { + pub fn first_children(&self) -> FirstChildren<'a, T, I> { FirstChildren(self.first_child()) } /// Returns an iterator over last children. - pub fn last_children(&self) -> LastChildren<'a, T> { + pub fn last_children(&self) -> LastChildren<'a, T, I> { LastChildren(self.last_child()) } /// Returns an iterator over children. - pub fn children(&self) -> Children<'a, T> { + pub fn children(&self) -> Children<'a, T, I> { Children { front: self.first_child(), back: self.last_child(), @@ -342,7 +342,7 @@ impl<'a, T: 'a> NodeRef<'a, T> { } /// Returns an iterator which traverses the subtree starting at this node. - pub fn traverse(&self) -> Traverse<'a, T> { + pub fn traverse(&self) -> Traverse<'a, T, I> { Traverse { root: Some(*self), edge: None, @@ -350,7 +350,7 @@ impl<'a, T: 'a> NodeRef<'a, T> { } /// Returns an iterator over this node and its descendants. - pub fn descendants(&self) -> Descendants<'a, T> { + pub fn descendants(&self) -> Descendants<'a, T, I> { Descendants(self.traverse()) } } diff --git a/src/lib.rs b/src/lib.rs index 365afb6..36d953c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,7 @@ )] use std::fmt::{self, Debug, Display, Formatter}; -use std::num::NonZeroUsize; +use std::hash::Hash; #[cfg(feature = "serde")] pub mod serde; @@ -45,35 +45,97 @@ pub mod serde; /// /// Always contains at least a root node. #[derive(Clone, PartialEq, Eq, Hash)] -pub struct Tree { - vec: Vec>, +pub struct Tree { + vec: Vec>, } -/// Node ID. -/// -/// Index into a `Tree`-internal `Vec`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct NodeId(NonZeroUsize); +/// ID +/// +/// Trait that can be implemented for custom tagged ids. +/// This allows IDs obtained from different trees to be differentiated from +/// one another at the type level. +pub trait ID: Debug + Clone + Copy + PartialEq + Eq + PartialOrd + Ord + Hash { + /// Given a usize not equal to `usize::MAX`, constructs an ID. + /// + /// # Safety + /// `n` must not equal `usize::MAX`. + /// (This is never the case for `Vec::len()`, that would mean it owns + /// the entire address space without leaving space even for its pointer.) + unsafe fn from_index(n: usize) -> Self; -impl NodeId { - // Safety: `n` must not equal `usize::MAX`. - // (This is never the case for `Vec::len()`, that would mean it owns - // the entire address space without leaving space even for its pointer.) - unsafe fn from_index(n: usize) -> Self { - NodeId(NonZeroUsize::new_unchecked(n + 1)) + /// Returns the same `n` usize that was passed into from_index + fn to_index(self) -> usize; + + /// Transmutes an ID from one tagged type to another + fn transmute(self) -> T { + // Safety: Adding 0 will never cause offset to go above `usize::MAX` + unsafe { self.transmute_offset(0) } } - fn to_index(self) -> usize { - self.0.get() - 1 + /// Transmutes an ID from one tagged type to another, adding the specified offset + /// + /// # Safety + /// `offset` must not be high enough to cause the internal index to go above + /// `usize::MAX`. (This is never the case when adding two `Vec::len()`` together, + /// that would mean it owns the entire address space without leaving space for + /// either pointer) + unsafe fn transmute_offset(self, offset: usize) -> T { + unsafe { T::from_index(self.to_index() + offset) } } } +/// Constructs a custom ID type to use in differentiating trees. +/// +/// # Calling +/// ``` +/// #[macro_use] extern crate ego_tree; +/// ids!{ +/// /// Used for tree type 1 +/// IdType1, +/// /// Used for tree type 2 +/// IdType2 +/// } +/// # fn main() { +/// let tree_one = Tree::new_tagged(); +/// let tree_two = Tree::new_tagged(); +/// // IDs from tree_one won't be accepted by tree_two +/// } +/// ``` +#[macro_export] +macro_rules! ids { + ($(#[$m:meta] $i:ident$(,)?)*) => { + $( + #[$m] + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct $i(::std::num::NonZeroUsize); + + impl $crate::ID for $i { + // Safety: `n` must not equal `usize::MAX`. + // (This is never the case for `Vec::len()`, that would mean it owns + // the entire address space without leaving space even for its pointer.) + unsafe fn from_index(n: usize) -> Self { + $i(unsafe { ::std::num::NonZeroUsize::new_unchecked(n + 1) }) + } + + fn to_index(self) -> usize { + self.0.get() - 1 + } + } + )* + }; +} + +ids!{ + /// Standard ID + NodeId +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] -struct Node { - parent: Option, - prev_sibling: Option, - next_sibling: Option, - children: Option<(NodeId, NodeId)>, +struct Node { + parent: Option, + prev_sibling: Option, + next_sibling: Option, + children: Option<(Id, Id)>, value: T, } @@ -81,11 +143,11 @@ fn _static_assert_size_of_node() { // "Instantiating" the generic `transmute` function without calling it // still triggers the magic compile-time check // that input and output types have the same `size_of()`. - let _ = std::mem::transmute::, [usize; 5]>; + let _ = std::mem::transmute::, [usize; 5]>; } -impl Node { - fn new(value: T) -> Self { +impl Node { + fn new(value: T) -> Node { Node { parent: None, prev_sibling: None, @@ -95,7 +157,7 @@ impl Node { } } - pub fn map(self, mut transform: F) -> Node + pub fn map(self, mut transform: F) -> Node where F: FnMut(T) -> U, { @@ -108,7 +170,7 @@ impl Node { } } - pub fn map_ref(&self, mut transform: F) -> Node + pub fn map_ref(&self, mut transform: F) -> Node where F: FnMut(&T) -> U, { @@ -120,41 +182,56 @@ impl Node { value: transform(&self.value), } } + + fn transmute_ids(self, transform: F) -> Node + where + F: (Fn(I) -> O) + Copy, + O: ID + { + Node { + parent: self.parent.map(transform), + prev_sibling: self.prev_sibling.map(transform), + next_sibling: self.next_sibling.map(transform), + children: self.children.map(|(id1, id2)| (transform(id1), transform(id2))), + value: self.value + } + + } } /// Node reference. #[derive(Debug)] -pub struct NodeRef<'a, T: 'a> { +pub struct NodeRef<'a, T: 'a, I: ID = NodeId> { /// Node ID. - id: NodeId, + id: I, /// Tree containing the node. - tree: &'a Tree, + tree: &'a Tree, - node: &'a Node, + node: &'a Node, } /// Node mutator. #[derive(Debug)] -pub struct NodeMut<'a, T: 'a> { +pub struct NodeMut<'a, T: 'a, I: ID = NodeId> { /// Node ID. - id: NodeId, + id: I, /// Tree containing the node. - tree: &'a mut Tree, + tree: &'a mut Tree, } // Trait implementations regardless of T. -impl<'a, T: 'a> Copy for NodeRef<'a, T> {} -impl<'a, T: 'a> Clone for NodeRef<'a, T> { +impl<'a, T: 'a, I: ID> Copy for NodeRef<'a, T, I> {} +impl<'a, T: 'a, I: ID> Clone for NodeRef<'a, T, I> { fn clone(&self) -> Self { *self } } -impl<'a, T: 'a> Eq for NodeRef<'a, T> {} -impl<'a, T: 'a> PartialEq for NodeRef<'a, T> { +impl<'a, T: 'a, I: ID> Eq for NodeRef<'a, T, I> {} +impl<'a, T: 'a, I: ID> PartialEq for NodeRef<'a, T, I> { fn eq(&self, other: &Self) -> bool { self.id == other.id && std::ptr::eq(self.tree, other.tree) @@ -165,8 +242,15 @@ impl<'a, T: 'a> PartialEq for NodeRef<'a, T> { impl Tree { /// Creates a tree with a root node. pub fn new(root: T) -> Self { + Self::new_tagged(root) + } +} + +impl Tree { + /// Creates a tree with a root node with tagged ids. + pub fn new_tagged(root: T) -> Self { Tree { - vec: vec![Node::new(root)], + vec: vec![Node::::new(root)] } } @@ -178,7 +262,7 @@ impl Tree { } /// Returns a reference to the specified node. - pub fn get(&self, id: NodeId) -> Option> { + pub fn get(&self, id: I) -> Option> { self.vec.get(id.to_index()).map(|node| NodeRef { id, node, @@ -187,23 +271,23 @@ impl Tree { } /// Returns a mutator of the specified node. - pub fn get_mut(&mut self, id: NodeId) -> Option> { + pub fn get_mut(&mut self, id: I) -> Option> { let exists = self.vec.get(id.to_index()).map(|_| ()); exists.map(move |_| NodeMut { id, tree: self }) } - unsafe fn node(&self, id: NodeId) -> &Node { + unsafe fn node(&self, id: I) -> &Node { self.vec.get_unchecked(id.to_index()) } - unsafe fn node_mut(&mut self, id: NodeId) -> &mut Node { + unsafe fn node_mut(&mut self, id: I) -> &mut Node { self.vec.get_unchecked_mut(id.to_index()) } /// Returns a reference to the specified node. /// # Safety /// The caller must ensure that `id` is a valid node ID. - pub unsafe fn get_unchecked(&self, id: NodeId) -> NodeRef<'_, T> { + pub unsafe fn get_unchecked(&self, id: I) -> NodeRef<'_, T, I> { NodeRef { id, node: self.node(id), @@ -214,23 +298,23 @@ impl Tree { /// Returns a mutator of the specified node. /// # Safety /// The caller must ensure that `id` is a valid node ID. - pub unsafe fn get_unchecked_mut(&mut self, id: NodeId) -> NodeMut<'_, T> { + pub unsafe fn get_unchecked_mut(&mut self, id: I) -> NodeMut<'_, T, I> { NodeMut { id, tree: self } } /// Returns a reference to the root node. - pub fn root(&self) -> NodeRef<'_, T> { - unsafe { self.get_unchecked(NodeId::from_index(0)) } + pub fn root(&self) -> NodeRef<'_, T, I> { + unsafe { self.get_unchecked(I::from_index(0)) } } /// Returns a mutator of the root node. - pub fn root_mut(&mut self) -> NodeMut<'_, T> { - unsafe { self.get_unchecked_mut(NodeId::from_index(0)) } + pub fn root_mut(&mut self) -> NodeMut<'_, T, I> { + unsafe { self.get_unchecked_mut(I::from_index(0)) } } /// Creates an orphan node. - pub fn orphan(&mut self, value: T) -> NodeMut<'_, T> { - let id = unsafe { NodeId::from_index(self.vec.len()) }; + pub fn orphan(&mut self, value: T) -> NodeMut<'_, T, I> { + let id = unsafe { I::from_index(self.vec.len()) }; self.vec.push(Node::new(value)); unsafe { self.get_unchecked_mut(id) } } @@ -238,13 +322,9 @@ impl Tree { /// Merge with another tree as orphan, returning the new root of tree being merged. // Allowing this for compactness. #[allow(clippy::option_map_unit_fn)] - pub fn extend_tree(&mut self, mut other_tree: Tree) -> NodeMut<'_, T> { + pub fn extend_tree(&mut self, mut other_tree: Tree) -> NodeMut<'_, T, I> { 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 offset_id = |id: I| unsafe { id.transmute_offset(offset) }; 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)); @@ -259,9 +339,25 @@ impl Tree { unsafe { self.get_unchecked_mut(other_tree_root_id) } } + /// Merge with another tree as orphan, returning the new root of tree being merged. + // Allowing this for compactness. + #[allow(clippy::option_map_unit_fn)] + pub fn extend_tree_transmute(&mut self, other_tree: Tree) -> NodeMut<'_, T, I> + where + O: ID + { + let offset = self.vec.len(); + let offset_id = |id: O| -> I { unsafe { id.transmute_offset::(offset) }}; + let other_tree_root_id = offset_id(other_tree.root().id); + let other = other_tree.vec.into_iter() + .map(|node| -> Node { node.transmute_ids(offset_id) }); + self.vec.extend(other); + unsafe { self.get_unchecked_mut(other_tree_root_id) } + } + /// Maps a `Tree` to `Tree` by applying a function to all node values, /// copying over the tree's structure and node ids untouched, consuming `self`. - pub fn map(self, mut transform: F) -> Tree + pub fn map(self, mut transform: F) -> Tree where F: FnMut(T) -> U, { @@ -276,7 +372,7 @@ impl Tree { /// Maps a `&Tree` to `Tree` by applying a function to all node values, /// copying over the tree's structure and node ids untouched. - pub fn map_ref(&self, mut transform: F) -> Tree + pub fn map_ref(&self, mut transform: F) -> Tree where F: FnMut(&T) -> U, { @@ -290,14 +386,14 @@ impl Tree { } } -impl<'a, T: 'a> NodeRef<'a, T> { +impl<'a, T: 'a, I: ID> NodeRef<'a, T, I> { /// Returns the ID of this node. - pub fn id(&self) -> NodeId { + pub fn id(&self) -> I { self.id } /// Returns the tree owning this node. - pub fn tree(&self) -> &'a Tree { + pub fn tree(&self) -> &'a Tree { self.tree } @@ -308,7 +404,7 @@ impl<'a, T: 'a> NodeRef<'a, T> { fn axis(&self, f: F) -> Option where - F: FnOnce(&Node) -> Option, + F: FnOnce(&Node) -> Option, { f(self.node).map(|id| unsafe { self.tree.get_unchecked(id) }) } @@ -349,18 +445,18 @@ impl<'a, T: 'a> NodeRef<'a, T> { } } -impl<'a, T: 'a> NodeMut<'a, T> { +impl<'a, T: 'a, I: ID> NodeMut<'a, T, I> { /// Returns the ID of this node. - pub fn id(&self) -> NodeId { + pub fn id(&self) -> I { self.id } /// Returns the tree owning this node. - pub fn tree(&mut self) -> &mut Tree { + pub fn tree(&mut self) -> &mut Tree { self.tree } - fn node(&mut self) -> &mut Node { + fn node(&mut self) -> &mut Node { unsafe { self.tree.node_mut(self.id) } } @@ -370,13 +466,13 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Downcast `NodeMut` to `NodeRef`. - pub fn as_ref(&mut self) -> NodeRef<'_, T> { + pub fn as_ref(&mut self) -> NodeRef<'_, T, I> { unsafe { self.tree.get_unchecked(self.id) } } - fn axis(&mut self, f: F) -> Option> + fn axis(&mut self, f: F) -> Option> where - F: FnOnce(&mut Node) -> Option, + F: FnOnce(&mut Node) -> Option, { let id = f(self.node()); id.map(move |id| unsafe { self.tree.get_unchecked_mut(id) }) @@ -384,7 +480,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { fn into_axis(mut self, f: F) -> Result where - F: FnOnce(&mut Node) -> Option, + F: FnOnce(&mut Node) -> Option, { let id = f(self.node()); match id { @@ -394,7 +490,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Returns the parent of this node. - pub fn parent(&mut self) -> Option> { + pub fn parent(&mut self) -> Option> { self.axis(|node| node.parent) } @@ -407,7 +503,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Returns the previous sibling of this node. - pub fn prev_sibling(&mut self) -> Option> { + pub fn prev_sibling(&mut self) -> Option> { self.axis(|node| node.prev_sibling) } @@ -420,7 +516,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Returns the next sibling of this node. - pub fn next_sibling(&mut self) -> Option> { + pub fn next_sibling(&mut self) -> Option> { self.axis(|node| node.next_sibling) } @@ -433,7 +529,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Returns the first child of this node. - pub fn first_child(&mut self) -> Option> { + pub fn first_child(&mut self) -> Option> { self.axis(|node| node.children.map(|(id, _)| id)) } @@ -446,7 +542,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Returns the last child of this node. - pub fn last_child(&mut self) -> Option> { + pub fn last_child(&mut self) -> Option> { self.axis(|node| node.children.map(|(_, id)| id)) } @@ -471,7 +567,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for each ancestor mutable node reference. pub fn for_each_ancestor<'b, F>(&'b mut self, mut f: F) where - F: FnMut(&mut NodeMut<'b, T>), + F: FnMut(&mut NodeMut<'b, T, I>), { let mut current = self.parent(); while let Some(mut node) = current { @@ -483,7 +579,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for each next sibling mutable node reference. pub fn for_each_next_sibling<'b, F>(&'b mut self, mut f: F) where - F: FnMut(&mut NodeMut<'b, T>), + F: FnMut(&mut NodeMut<'b, T, I>), { let mut current = self.next_sibling(); while let Some(mut node) = current { @@ -495,7 +591,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for each previout sibling mutable node reference. pub fn for_each_prev_sibling<'b, F>(&'b mut self, mut f: F) where - F: FnMut(&mut NodeMut<'b, T>), + F: FnMut(&mut NodeMut<'b, T, I>), { let mut current = self.prev_sibling(); while let Some(mut node) = current { @@ -507,7 +603,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for this node and each sibling mutable node reference. pub fn for_each_sibling(&mut self, mut f: F) where - F: for<'b> FnMut(&mut NodeMut<'b, T>), + F: for<'b> FnMut(&mut NodeMut<'b, T, I>), { self.for_each_prev_sibling(&mut f); f(self); @@ -517,7 +613,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for each children mutable node reference. pub fn for_each_child(&mut self, mut f: F) where - F: for<'b> FnMut(&mut NodeMut<'b, T>), + F: for<'b> FnMut(&mut NodeMut<'b, T, I>), { let Some(mut first_child) = self.first_child() else { return; @@ -529,7 +625,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// Apply function for this node and each descendant mutable node reference. pub fn for_each_descendant(&mut self, mut f: F) where - F: FnMut(&mut NodeMut<'_, T>), + F: FnMut(&mut NodeMut<'_, T, I>), { let id = self.id(); @@ -579,35 +675,52 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Appends a new child to this node. - pub fn append(&mut self, value: T) -> NodeMut<'_, T> { + pub fn append(&mut self, value: T) -> NodeMut<'_, T, I> { let id = self.tree.orphan(value).id; self.append_id(id) } /// Prepends a new child to this node. - pub fn prepend(&mut self, value: T) -> NodeMut<'_, T> { + pub fn prepend(&mut self, value: T) -> NodeMut<'_, T, I> { let id = self.tree.orphan(value).id; self.prepend_id(id) } /// Appends a subtree, return the root of the merged subtree. - pub fn append_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T> { + pub fn append_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T, I> { let root_id = self.tree.extend_tree(subtree).id; self.append_id(root_id) } + /// Transmutes and appends a subtree, return the root of the merged subtree + pub fn append_transmute_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T, I> + where + O: ID + { + let root_id = self.tree.extend_tree_transmute(subtree).id; + self.append_id(root_id) + } + /// Prepends a subtree, return the root of the merged subtree. - pub fn prepend_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T> { + pub fn prepend_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T, I> { let root_id = self.tree.extend_tree(subtree).id; self.prepend_id(root_id) } + /// Transmutes and prepends a subtree, return the root of the merged subtree. + pub fn prepend_transmute_subtree(&mut self, subtree: Tree) -> NodeMut<'_, T, I> + where + O: ID + { + let root_id = self.tree.extend_tree_transmute(subtree).id; + self.prepend_id(root_id) + } /// Inserts a new sibling before this node. /// /// # Panics /// /// Panics if this node is an orphan. - pub fn insert_before(&mut self, value: T) -> NodeMut<'_, T> { + pub fn insert_before(&mut self, value: T) -> NodeMut<'_, T, I> { let id = self.tree.orphan(value).id; self.insert_id_before(id) } @@ -617,7 +730,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// # Panics /// /// Panics if this node is an orphan. - pub fn insert_after(&mut self, value: T) -> NodeMut<'_, T> { + pub fn insert_after(&mut self, value: T) -> NodeMut<'_, T, I> { let id = self.tree.orphan(value).id; self.insert_id_after(id) } @@ -664,7 +777,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// # Panics /// /// Panics if `new_child_id` is not valid. - pub fn append_id(&mut self, new_child_id: NodeId) -> NodeMut<'_, T> { + pub fn append_id(&mut self, new_child_id: I) -> NodeMut<'_, T, I> { assert_ne!( self.id(), new_child_id, @@ -703,7 +816,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// # Panics /// /// Panics if `new_child_id` is not valid. - pub fn prepend_id(&mut self, new_child_id: NodeId) -> NodeMut<'_, T> { + pub fn prepend_id(&mut self, new_child_id: I) -> NodeMut<'_, T, I> { assert_ne!( self.id(), new_child_id, @@ -743,7 +856,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// /// - Panics if `new_sibling_id` is not valid. /// - Panics if this node is an orphan. - pub fn insert_id_before(&mut self, new_sibling_id: NodeId) -> NodeMut<'_, T> { + pub fn insert_id_before(&mut self, new_sibling_id: I) -> NodeMut<'_, T, I> { assert_ne!( self.id(), new_sibling_id, @@ -786,7 +899,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// /// - Panics if `new_sibling_id` is not valid. /// - Panics if this node is an orphan. - pub fn insert_id_after(&mut self, new_sibling_id: NodeId) -> NodeMut<'_, T> { + pub fn insert_id_after(&mut self, new_sibling_id: I) -> NodeMut<'_, T, I> { assert_ne!( self.id(), new_sibling_id, @@ -828,7 +941,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// # Panics /// /// Panics if `from_id` is not valid. - pub fn reparent_from_id_append(&mut self, from_id: NodeId) { + pub fn reparent_from_id_append(&mut self, from_id: I) { assert_ne!( self.id(), from_id, @@ -872,7 +985,7 @@ impl<'a, T: 'a> NodeMut<'a, T> { /// # Panics /// /// Panics if `from_id` is not valid. - pub fn reparent_from_id_prepend(&mut self, from_id: NodeId) { + pub fn reparent_from_id_prepend(&mut self, from_id: I) { assert_ne!( self.id(), from_id, @@ -912,19 +1025,19 @@ impl<'a, T: 'a> NodeMut<'a, T> { } /// Clone a subtree as orphan, returning the cloned root node. - pub fn clone_subtree(&mut self) -> NodeMut<'_, T> + pub fn clone_subtree(&mut self) -> NodeMut<'_, T, I> where T: Clone, { - enum Edge { + enum Edge { Open { - cur: NodeId, - cloned_parent: Option, + cur: I, + cloned_parent: Option, }, Close { - cur: NodeId, - cloned_cur: NodeId, - cloned_parent: Option, + cur: I, + cloned_cur: I, + cloned_parent: Option, }, } @@ -1049,6 +1162,24 @@ pub mod iter; /// }; /// # } /// ``` +/// Specify the ID type by adding it as the first argument +/// ``` +/// #[macro_use] extern crate ego_tree; +/// # fn main() { +/// ids! { +/// /// For demo purposes +/// MyCustomID +/// } +/// let tagged_tree = tree!{ +/// MyCustomID, +/// "root" => { +/// "child_1", +/// "child_2" +/// } +/// }; +/// # } +/// ``` +/// #[macro_export] macro_rules! tree { (@ $n:ident { }) => { }; @@ -1104,9 +1235,25 @@ macro_rules! tree { tree } }; + + ($t:ty, $root:expr) => { + let tree: $crate::Tree<_, $t> = $crate::Tree::new_tagged($root); + tree + }; + + ($t:ty, $root:expr => $children:tt) => { + { + let mut tree: $crate::Tree<_, $t> = $crate::Tree::new_tagged($root); + { + let mut node = tree.root_mut(); + tree!(@ node $children); + } + tree + } + }; } -impl Debug for Tree { +impl Debug for Tree { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { use crate::iter::Edge; if f.alternate() { @@ -1142,7 +1289,7 @@ impl Debug for Tree { // Handles display mod display; -impl Display for Tree { +impl Display for Tree { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { use crate::display::Indentation; use crate::iter::Edge; diff --git a/tests/subtree.rs b/tests/subtree.rs index 30a279d..8fd85e3 100644 --- a/tests/subtree.rs +++ b/tests/subtree.rs @@ -1,4 +1,10 @@ -use ego_tree::tree; +use ego_tree::{ids, tree}; + +ids! { + /// His + TestID +} + #[test] fn prepend_subtree() { @@ -9,7 +15,7 @@ fn prepend_subtree() { let subtree = tree!('f' => { 'g', 'h' => { 'i', 'j' } }); let mut root_subtree = node.prepend_subtree(subtree); - assert_eq!(root_subtree.parent().unwrap().value(), &'b'); + assert_eq!(root_subtree.parent().unwrap().value(), &'b'); assert_eq!( root_subtree.parent().unwrap().parent().unwrap().value(), &'a' @@ -33,3 +39,37 @@ fn append_subtree() { let new_tree = tree!('a' => { 'b', 'c', 'd' => { 'e', 'f' } }); assert_eq!(format!("{:#?}", tree), format!("{:#?}", new_tree)); } + +#[test] +fn prepend_transmute_subtree() { + let mut tree = tree!(TestID, 'a' => { 'b', 'c' => { 'd', 'e' } }); + let node_id = tree.root().first_child().unwrap().id(); + let mut node = tree.get_mut(node_id).unwrap(); + assert_eq!(node.value(), &'b'); + + let subtree = tree!('f' => { 'g', 'h' => { 'i', 'j' } }); + let mut root_subtree = node.prepend_transmute_subtree(subtree); + assert_eq!(root_subtree.parent().unwrap().value(), &'b'); + assert_eq!( + root_subtree.parent().unwrap().parent().unwrap().value(), + &'a' + ); + + let new_tree = + tree!(TestID, 'a' => { 'b' => { 'f' => { 'g', 'h' => { 'i', 'j' } } }, 'c' => { 'd', 'e' } }); + assert_eq!(format!("{:#?}", tree), format!("{:#?}", new_tree)); +} + +#[test] +fn append_transmute_subtree() { + let mut tree = tree!('a' => { 'b', 'c', 'd' }); + let mut node = tree.root_mut(); + assert_eq!(node.value(), &'a'); + + let subtree = tree!(TestID, 'e' => { 'f', 'g' => {'h'}}); + let mut root_subtree = node.append_transmute_subtree(subtree); + assert_eq!(root_subtree.parent().unwrap().value(), &'a'); + + let new_tree = tree!('a' => { 'b', 'c', 'd', 'e' => { 'f', 'g' => {'h'} } }); + assert_eq!(format!("{:#?}", tree), format!("{:#?}", new_tree)); +} \ No newline at end of file