#![warn(clippy::pedantic, missing_debug_implementations, missing_docs)]
use std::alloc;
use std::fmt;
use std::ptr;
use std::ptr::NonNull;
#[allow(clippy::module_name_repetitions)]
#[derive(Debug)]
pub struct SyntaxTree<T> {
root: Option<NonNull<Node<T>>>,
}
pub const INDENT: &str = " ";
impl<T: fmt::Display> fmt::Display for SyntaxTree<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for Element { item, depth } in self.iter() {
writeln!(f, "{}{item}", INDENT.repeat(depth))?;
}
Ok(())
}
}
type NodePredecessor<T> = Predecessor<NonNull<Node<T>>>;
impl<T> SyntaxTree<T> {
#[must_use]
pub fn cursor(&self) -> Cursor<'_, T> {
Cursor {
predecessor: None,
current: self.root,
tree: self,
}
}
pub fn cursor_mut(&mut self) -> CursorMut<'_, T> {
CursorMut {
predecessor: None,
current: self.root,
tree: self,
}
}
#[must_use]
pub fn len(&self) -> usize {
self.iter().count()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.root.is_some()
}
#[must_use]
pub fn iter(&self) -> Iter<'_, T> {
let stack = if let Some(root) = self.root {
vec![(root, 0)]
} else {
Vec::new()
};
Iter {
stack,
__marker: self,
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
let stack = if let Some(root) = self.root {
vec![(root, 0)]
} else {
Vec::new()
};
IterMut {
stack,
__marker: self,
}
}
}
impl<T> Default for SyntaxTree<T> {
fn default() -> Self {
Self { root: None }
}
}
impl<T: Clone> Clone for SyntaxTree<T> {
fn clone(&self) -> Self {
if let Some(root) = self.root {
unsafe {
let root_ptr = {
let ptr: *mut Node<T> =
alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>();
ptr::copy_nonoverlapping(root.as_ptr(), ptr, 1);
NonNull::new(ptr).unwrap()
};
let mut stack = vec![root_ptr];
while let Some(mut current) = stack.pop() {
if let Some(next) = &mut current.as_mut().next {
let next_ptr = {
let ptr =
alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>();
ptr::copy_nonoverlapping(next.as_ptr(), ptr, 1);
NonNull::new(ptr).unwrap()
};
*next = next_ptr;
stack.push(next_ptr);
}
if let Some(child) = &mut current.as_mut().child {
let child_ptr = {
let ptr =
alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>();
ptr::copy_nonoverlapping(child.as_ptr(), ptr, 1);
NonNull::new(ptr).unwrap()
};
*child = child_ptr;
stack.push(child_ptr);
}
}
Self {
root: Some(root_ptr),
}
}
} else {
Self { root: None }
}
}
}
impl<T> From<T> for SyntaxTree<T> {
fn from(element: T) -> Self {
let ptr = unsafe {
let ptr = alloc::alloc(alloc::Layout::new::<Node<T>>()).cast();
ptr::write(
ptr,
Node {
element,
predecessor: None,
child: None,
next: None,
},
);
NonNull::new_unchecked(ptr)
};
Self { root: Some(ptr) }
}
}
#[derive(Debug)]
pub struct Iter<'a, T> {
stack: Vec<(NonNull<Node<T>>, usize)>,
__marker: &'a SyntaxTree<T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = Element<&'a T>;
fn next(&mut self) -> Option<Self::Item> {
let current_opt = self.stack.pop();
unsafe {
if let Some((current, depth)) = current_opt {
if let Some(next) = current.as_ref().next {
self.stack.push((next, depth));
}
if let Some(child) = current.as_ref().child {
self.stack.push((child, depth + 1));
}
Some(Element {
item: ¤t.as_ref().element,
depth,
})
} else {
None
}
}
}
}
#[derive(Debug)]
pub struct IterMut<'a, T> {
stack: Vec<(NonNull<Node<T>>, usize)>,
__marker: &'a mut SyntaxTree<T>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = Element<&'a mut T>;
fn next(&mut self) -> Option<Self::Item> {
let current_opt = self.stack.pop();
unsafe {
if let Some((mut current, depth)) = current_opt {
if let Some(next) = current.as_ref().next {
self.stack.push((next, depth));
}
if let Some(child) = current.as_ref().child {
self.stack.push((child, depth + 1));
}
Some(Element {
item: &mut current.as_mut().element,
depth,
})
} else {
None
}
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct Element<T> {
pub item: T,
pub depth: usize,
}
#[derive(Debug)]
pub struct Cursor<'a, T> {
predecessor: Option<NodePredecessor<T>>,
current: Option<NonNull<Node<T>>>,
tree: &'a SyntaxTree<T>,
}
impl<'a, T> Clone for Cursor<'a, T> {
fn clone(&self) -> Self {
Self {
predecessor: self.predecessor,
current: self.current,
tree: self.tree,
}
}
}
impl<T: std::fmt::Debug> Cursor<'_, T> {
#[must_use]
pub fn root(&self) -> Option<&T> {
self.tree.root.map(|r| unsafe { &r.as_ref().element })
}
#[must_use]
pub fn current(&self) -> Option<&T> {
self.current.map(|ptr| unsafe { &ptr.as_ref().element })
}
pub fn move_pred(&mut self) {
if let Some(predecessor) = self.predecessor {
self.current = Some(predecessor.unwrap());
self.predecessor =
unsafe { predecessor.unwrap().as_ref().predecessor.as_ref().copied() };
}
}
pub fn move_next(&mut self) {
if let Some(current) = self.current {
self.predecessor = Some(Predecessor::Previous(current));
self.current = unsafe { current.as_ref().next };
}
}
pub fn move_child(&mut self) {
if let Some(current) = self.current {
self.predecessor = Some(Predecessor::Parent(current));
let opt = unsafe { current.as_ref().child.as_ref() };
self.current = opt.copied();
}
}
pub fn move_parent(&mut self) -> bool {
loop {
match self.predecessor {
Some(Predecessor::Previous(previous)) => {
self.current = Some(previous);
self.predecessor = unsafe { previous.as_ref().predecessor };
}
Some(Predecessor::Parent(parent)) => {
self.current = Some(parent);
self.predecessor = unsafe { parent.as_ref().predecessor };
break true;
}
None => break false,
}
}
}
#[must_use]
pub fn peek_next(&self) -> Option<&T> {
if let Some(current) = self.current {
unsafe { current.as_ref().next.map(|n| &n.as_ref().element) }
} else {
None
}
}
#[must_use]
pub fn peek_parent(&self) -> Option<&T> {
self.peek_predecessor().and_then(Predecessor::parent)
}
#[must_use]
pub fn peek_previous(&self) -> Option<&T> {
self.peek_predecessor().and_then(Predecessor::previous)
}
#[must_use]
pub fn peek_predecessor(&self) -> Option<Predecessor<&T>> {
self.predecessor
.map(|p| unsafe { p.map(|p| &p.as_ref().element) })
}
#[must_use]
pub fn peek_child(&self) -> Option<&T> {
if let Some(current) = self.current {
unsafe { current.as_ref().child.map(|n| &n.as_ref().element) }
} else {
None
}
}
}
impl<'a, T> std::ops::Deref for CursorMut<'a, T> {
type Target = Cursor<'a, T>;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const CursorMut<'_, T>).cast() }
}
}
impl<'a, T> std::ops::DerefMut for CursorMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut CursorMut<'_, T>).cast() }
}
}
#[derive(Debug)]
pub struct CursorMut<'a, T> {
predecessor: Option<NodePredecessor<T>>,
current: Option<NonNull<Node<T>>>,
tree: &'a mut SyntaxTree<T>,
}
impl<T> CursorMut<'_, T> {
pub fn root_mut(&mut self) -> Option<&mut T> {
self.tree
.root
.map(|mut r| unsafe { &mut r.as_mut().element })
}
pub fn current_mut(&mut self) -> Option<&mut T> {
self.current
.map(|mut ptr| unsafe { &mut ptr.as_mut().element })
}
pub fn insert_predecessor(&mut self, item: T) {
let ptr = unsafe { alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>() };
match (self.current, self.predecessor) {
(Some(mut current), Some(previous)) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(previous),
child: None,
next: Some(current),
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
match previous {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = Some(ptr);
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = Some(ptr);
}
}
let pred = Some(Predecessor::Previous(ptr));
current.as_mut().predecessor = pred;
self.predecessor = pred;
},
(Some(mut current), None) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: None,
child: None,
next: Some(current),
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
let pred = Some(Predecessor::Previous(ptr));
current.as_mut().predecessor = pred;
self.predecessor = pred;
self.tree.root = Some(ptr);
},
(None, Some(previous)) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(previous),
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
match previous {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = Some(ptr);
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = Some(ptr);
}
}
self.current = Some(ptr);
},
(None, None) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: None,
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
self.current = Some(ptr);
self.tree.root = Some(ptr);
},
}
}
pub fn insert_next(&mut self, item: T) {
let ptr = unsafe { alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>() };
match (self.current, self.predecessor) {
(Some(mut current), _) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Previous(current)),
child: None,
next: current.as_ref().next,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
if let Some(mut next) = current.as_ref().next {
next.as_mut().predecessor = Some(Predecessor::Previous(ptr));
}
current.as_mut().next = Some(ptr);
},
(None, Some(predecessor)) => match predecessor {
Predecessor::Parent(mut parent) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Parent(parent)),
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
parent.as_mut().child = Some(ptr);
self.current = Some(ptr);
},
Predecessor::Previous(mut previous) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Previous(previous)),
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
previous.as_mut().next = Some(ptr);
self.current = Some(ptr);
},
},
(None, None) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: None,
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
self.current = Some(ptr);
self.tree.root = Some(ptr);
},
}
}
pub fn insert_child(&mut self, item: T) {
let ptr = unsafe { alloc::alloc(alloc::Layout::new::<Node<T>>()).cast::<Node<T>>() };
match (self.current, self.predecessor) {
(Some(mut current), _) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Parent(current)),
child: None,
next: current.as_ref().next,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
if let Some(mut child) = current.as_ref().child {
child.as_mut().predecessor = Some(Predecessor::Previous(ptr));
}
current.as_mut().child = Some(ptr);
},
(None, Some(predecessor)) => match predecessor {
Predecessor::Parent(mut parent) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Parent(parent)),
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
parent.as_mut().child = Some(ptr);
self.current = Some(ptr);
},
Predecessor::Previous(mut previous) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: Some(Predecessor::Previous(previous)),
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
previous.as_mut().next = Some(ptr);
self.current = Some(ptr);
},
},
(None, None) => unsafe {
ptr::write(
ptr,
Node {
element: item,
predecessor: None,
child: None,
next: None,
},
);
let ptr = NonNull::new(ptr).unwrap_unchecked();
self.current = Some(ptr);
self.tree.root = Some(ptr);
},
}
}
pub fn remove_current(&mut self) {
match (self.current, self.predecessor) {
(Some(current), Some(predecessor)) => unsafe {
self.current = current.as_ref().next;
match predecessor {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = current.as_ref().next;
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = current.as_ref().next;
}
}
if let Some(mut next) = current.as_ref().next {
next.as_mut().predecessor = Some(predecessor);
}
if let Some(child) = current.as_ref().child {
let mut stack = vec![child];
while let Some(next) = stack.pop() {
if let Some(child) = next.as_ref().child {
stack.push(child);
}
if let Some(next) = next.as_ref().next {
stack.push(next);
}
alloc::dealloc(next.as_ptr().cast(), alloc::Layout::new::<Node<T>>());
}
}
alloc::dealloc(current.as_ptr().cast(), alloc::Layout::new::<Node<T>>());
},
(Some(current), None) => unsafe {
self.current = current.as_ref().next;
self.tree.root = current.as_ref().next;
if let Some(mut next) = current.as_ref().next {
next.as_mut().predecessor = None;
}
if let Some(child) = current.as_ref().child {
let mut stack = vec![child];
while let Some(next) = stack.pop() {
if let Some(child) = next.as_ref().child {
stack.push(child);
}
if let Some(next) = next.as_ref().next {
stack.push(next);
}
alloc::dealloc(next.as_ptr().cast(), alloc::Layout::new::<Node<T>>());
}
}
alloc::dealloc(current.as_ptr().cast(), alloc::Layout::new::<Node<T>>());
},
(None, _) => {}
}
}
#[allow(clippy::needless_pass_by_value)]
pub fn splice_after(&mut self, tree: SyntaxTree<T>) {
if let Some(mut tree_root) = tree.root {
match (self.current, self.predecessor) {
(Some(mut current), _) => unsafe {
if let Some(mut self_next) = current.as_ref().next {
let mut tree_last = tree_root;
while let Some(next) = tree_last.as_ref().next {
tree_last = next;
}
tree_last.as_mut().next = Some(self_next);
self_next.as_mut().predecessor = Some(Predecessor::Previous(tree_last));
tree_root.as_mut().predecessor = Some(Predecessor::Previous(current));
current.as_mut().next = tree.root;
} else {
tree_root.as_mut().predecessor = Some(Predecessor::Previous(current));
current.as_mut().next = tree.root;
}
},
(None, Some(predecessor)) => unsafe {
self.current = Some(tree_root);
match predecessor {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = Some(tree_root);
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = Some(tree_root);
}
}
tree_root.as_mut().predecessor = Some(predecessor);
},
(None, None) => {
self.current = tree.root;
self.tree.root = tree.root;
}
}
}
}
#[allow(clippy::needless_pass_by_value)]
pub fn splice_before(&mut self, tree: SyntaxTree<T>) {
if let Some(mut tree_root) = tree.root {
match (self.current, self.predecessor) {
(Some(mut current), Some(previous)) => unsafe {
let mut tree_last = tree_root;
while let Some(next) = tree_last.as_ref().next {
tree_last = next;
}
tree_last.as_mut().next = Some(current);
let pred = Some(Predecessor::Previous(tree_last));
current.as_mut().predecessor = pred;
self.predecessor = pred;
match previous {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = Some(tree_root);
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = Some(tree_root);
}
}
},
(Some(mut current), None) => unsafe {
let mut tree_last = tree_root;
while let Some(next) = tree_last.as_ref().next {
tree_last = next;
}
tree_last.as_mut().next = Some(current);
let pred = Some(Predecessor::Previous(tree_last));
current.as_mut().predecessor = pred;
self.predecessor = pred;
self.tree.root = Some(tree_root);
},
(None, Some(previous)) => unsafe {
self.current = Some(tree_root);
match previous {
Predecessor::Parent(mut parent) => {
parent.as_mut().child = Some(tree_root);
}
Predecessor::Previous(mut previous) => {
previous.as_mut().next = Some(tree_root);
}
}
tree_root.as_mut().predecessor = Some(previous);
},
(None, None) => {
self.current = tree.root;
self.tree.root = tree.root;
}
}
}
}
pub fn split_after(&mut self) -> SyntaxTree<T> {
match (self.current, self.predecessor) {
(Some(mut current), _) => unsafe {
if let Some(next) = current.as_ref().next {
current.as_mut().next = None;
SyntaxTree { root: Some(next) }
} else {
SyntaxTree { root: None }
}
},
(None, _) => SyntaxTree { root: None },
}
}
pub fn split_before(&mut self) -> SyntaxTree<T> {
match (self.current, self.predecessor) {
(Some(mut current), Some(previous)) => unsafe {
previous.unwrap().as_mut().next = None;
self.predecessor = None;
current.as_mut().predecessor = None;
let temp = SyntaxTree {
root: self.tree.root,
};
self.tree.root = Some(current);
temp
},
(None, Some(previous)) => unsafe {
previous.unwrap().as_mut().next = None;
self.predecessor = None;
let temp = SyntaxTree {
root: self.tree.root,
};
self.tree.root = None;
temp
},
(_, None) => SyntaxTree { root: None },
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Predecessor<T> {
Parent(T),
Previous(T),
}
#[allow(dead_code)]
impl<T> Predecessor<T> {
pub fn parent(self) -> Option<T> {
match self {
Self::Parent(x) => Some(x),
Self::Previous(_) => None,
}
}
pub fn previous(self) -> Option<T> {
match self {
Self::Parent(_) => None,
Self::Previous(x) => Some(x),
}
}
pub fn unwrap(self) -> T {
match self {
Self::Previous(x) | Self::Parent(x) => x,
}
}
pub fn as_ref(&self) -> Predecessor<&T> {
match self {
Self::Parent(x) => Predecessor::Parent(x),
Self::Previous(x) => Predecessor::Previous(x),
}
}
pub fn as_mut(&mut self) -> Predecessor<&mut T> {
match self {
Self::Parent(x) => Predecessor::Parent(x),
Self::Previous(x) => Predecessor::Previous(x),
}
}
pub fn map<P>(self, f: impl Fn(T) -> P) -> Predecessor<P> {
match self {
Self::Previous(x) => Predecessor::Previous(f(x)),
Self::Parent(x) => Predecessor::Parent(f(x)),
}
}
}
#[derive(Debug)]
struct Node<T> {
element: T,
predecessor: Option<NodePredecessor<T>>,
child: Option<NonNull<Node<T>>>,
next: Option<NonNull<Node<T>>>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display() {
let mut tree = SyntaxTree::<u8>::default();
let mut cursor = tree.cursor_mut();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_next(0);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&0));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_child(1);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&0));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), Some(&1));
cursor.move_child();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&0)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_next(2);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&0)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
assert_eq!(cursor.peek_child(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_child(3);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), Some(&3));
cursor.move_parent();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&0));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), Some(&1));
cursor.insert_next(4);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&0));
assert_eq!(cursor.peek_next(), Some(&4));
assert_eq!(cursor.peek_child(), Some(&1));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&0)));
assert_eq!(cursor.current(), Some(&4));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_child(5);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&0)));
assert_eq!(cursor.current(), Some(&4));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), Some(&5));
cursor.move_child();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&4)));
assert_eq!(cursor.current(), Some(&5));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_next(6);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&4)));
assert_eq!(cursor.current(), Some(&5));
assert_eq!(cursor.peek_next(), Some(&6));
assert_eq!(cursor.peek_child(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&5)));
assert_eq!(cursor.current(), Some(&6));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), None);
cursor.insert_child(7);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&5)));
assert_eq!(cursor.current(), Some(&6));
assert_eq!(cursor.peek_next(), None);
assert_eq!(cursor.peek_child(), Some(&7));
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &0, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 1 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 1 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 2 }));
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &5, depth: 1 }));
assert_eq!(iter.next(), Some(Element { item: &6, depth: 1 }));
assert_eq!(iter.next(), Some(Element { item: &7, depth: 2 }));
let expected = format!(
"\
0\n\
{INDENT}1\n\
{INDENT}2\n\
{INDENT}{INDENT}3\n\
4\n\
{INDENT}5\n\
{INDENT}6\n\
{INDENT}{INDENT}7\n\
"
);
assert_eq!(tree.to_string(), expected);
}
#[test]
fn insert_predecessor() {
let mut tree = SyntaxTree::<u8>::default();
let mut cursor = tree.cursor_mut();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_predecessor(1);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.insert_predecessor(2);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), Some(&1));
cursor.insert_predecessor(3);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&3)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), Some(&1));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&3)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), Some(&1));
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
}
#[test]
fn insert_next() {
let mut tree = SyntaxTree::<u8>::default();
let mut cursor = tree.cursor_mut();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(1);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(2);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.insert_next(3);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&3));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&3)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&3)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&3));
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&3));
}
#[test]
fn remove() {
let mut tree = SyntaxTree::<u8>::default();
let mut cursor = tree.cursor_mut();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(1);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(2);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.insert_next(3);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&3));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&3)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_pred();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&3));
cursor.remove_current();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.remove_current();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
}
#[test]
fn clone() {
let mut tree = SyntaxTree::<u8>::default();
let mut cursor = tree.cursor_mut();
cursor.insert_next(1);
cursor.insert_predecessor(2);
cursor.insert_next(3);
cursor.insert_predecessor(4);
cursor.insert_next(5);
let tree_clone = tree.clone();
tree.iter().zip(tree_clone.iter()).all(|(a, b)| a == b);
}
#[test]
fn indexing() {
let mut tree = SyntaxTree::<u8>::default();
let mut iter = tree.iter();
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 0);
tree.cursor_mut().insert_next(1);
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 1);
tree.cursor_mut().insert_predecessor(2);
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 2);
tree.cursor_mut().insert_next(3);
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 3);
tree.cursor_mut().insert_predecessor(4);
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 4);
tree.cursor_mut().insert_next(5);
let mut iter = tree.iter();
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &5, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(tree.len(), 5);
}
#[test]
fn splice_and_split_after() {
let mut tree_one = SyntaxTree::<u8>::default();
let mut cursor_one = tree_one.cursor_mut();
cursor_one.insert_next(1);
cursor_one.insert_next(2);
cursor_one.insert_next(3);
let mut tree_two = SyntaxTree::<u8>::default();
let mut cursor_two = tree_two.cursor_mut();
cursor_two.insert_next(4);
cursor_two.insert_next(5);
cursor_two.insert_next(6);
cursor_one.splice_after(tree_two);
let mut iter = tree_one.iter();
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &6, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &5, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let mut cursor = tree_one.cursor_mut();
cursor.move_next();
cursor.move_next();
let tree_three = cursor.split_after();
let mut iter = tree_one.iter();
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &6, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let mut iter = tree_three.iter();
assert_eq!(iter.next(), Some(Element { item: &5, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn splice_and_split_before() {
let mut tree_one = SyntaxTree::<u8>::default();
let mut cursor_one = tree_one.cursor_mut();
cursor_one.insert_next(1);
cursor_one.insert_next(2);
cursor_one.insert_next(3);
let mut tree_two = SyntaxTree::<u8>::default();
let mut cursor_two = tree_two.cursor_mut();
cursor_two.insert_next(4);
cursor_two.insert_next(5);
cursor_two.insert_next(6);
cursor_one.splice_before(tree_two);
let mut iter = tree_one.iter();
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &6, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &5, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let mut cursor = tree_one.cursor_mut();
cursor.move_next();
cursor.move_next();
cursor.move_next();
let tree_three = cursor.split_before();
let mut iter = tree_one.iter();
assert_eq!(iter.next(), Some(Element { item: &1, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &3, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &2, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let mut iter = tree_three.iter();
assert_eq!(iter.next(), Some(Element { item: &4, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &6, depth: 0 }));
assert_eq!(iter.next(), Some(Element { item: &5, depth: 0 }));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn move_parent() {
let mut tree_one = SyntaxTree::<u8>::default();
let mut cursor = tree_one.cursor_mut();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(1);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(2);
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(3);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&1)));
assert_eq!(cursor.current(), Some(&2));
assert_eq!(cursor.peek_next(), Some(&3));
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), None);
cursor.move_child();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&3)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(4);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Parent(&3)));
assert_eq!(cursor.current(), Some(&4));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&4)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(5);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&4)));
assert_eq!(cursor.current(), Some(&5));
assert_eq!(cursor.peek_next(), None);
cursor.move_next();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&5)));
assert_eq!(cursor.current(), None);
assert_eq!(cursor.peek_next(), None);
cursor.insert_next(6);
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&5)));
assert_eq!(cursor.current(), Some(&6));
assert_eq!(cursor.peek_next(), None);
cursor.move_parent();
assert_eq!(cursor.peek_predecessor(), Some(Predecessor::Previous(&2)));
assert_eq!(cursor.current(), Some(&3));
assert_eq!(cursor.peek_next(), None);
cursor.move_parent();
assert_eq!(cursor.peek_predecessor(), None);
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
}
}