use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;
use std::mem;
pub use level_tree::{Tree, gen_branch_level as gen_level};
use adapton::macros::*;
use adapton::engine::*;
#[derive(Debug,PartialEq,Eq,Hash)]
pub struct Cursor<E: TreeUpdate+Debug+Clone+Eq+Hash+'static> {
dirty: bool,
l_forest: Vec<(bool,Tree<E>)>,
tree: Option<Tree<E>>,
r_forest: Vec<(bool,Tree<E>)>,
}
impl<E: TreeUpdate+Debug+Clone+Eq+Hash+'static> Clone for Cursor<E> {
fn clone(&self) -> Self {
Cursor {
dirty: self.dirty,
l_forest: self.l_forest.clone(),
tree: self.tree.clone(),
r_forest: self.r_forest.clone(),
}
}
}
pub trait TreeUpdate where Self: Sized{
fn rebuild(l_branch: Option<&Self>, old_data: &Self, level: u32, name: Option<Name>, r_branch: Option<&Self>) -> Self;
}
pub trait DeriveTreeUpdate{}
impl<E: DeriveTreeUpdate + Clone> TreeUpdate for E {
#[allow(unused_variables)]
fn rebuild(l_branch: Option<&Self>, old_data: &Self, level: u32, name: Option<Name>, r_branch: Option<&Self>) -> Self { old_data.clone() }
}
#[derive(Clone,Copy,PartialEq,Eq)]
pub enum Force {
No,
Yes,
Discard,
}
#[derive(Clone,Copy,PartialEq,Eq)]
pub enum UpResult {
Fail,
Left,
Right,
}
fn peek_op<E: Debug+Clone+Eq+Hash+'static>(op: &Option<Tree<E>>) -> Option<E> {
match *op {
None => None,
Some(ref t) => Some(t.peek())
}
}
const DEFAULT_DEPTH: usize = 30;
impl<E: TreeUpdate+Debug+Clone+Eq+Hash+'static>
From<Tree<E>> for Cursor<E> {
fn from(tree: Tree<E>) -> Self {
Cursor{
dirty: false,
l_forest: Vec::with_capacity(DEFAULT_DEPTH),
tree: Some(tree),
r_forest: Vec::with_capacity(DEFAULT_DEPTH),
}
}
}
impl<'a,E: TreeUpdate+Debug+Clone+Eq+Hash+'static> Cursor<E> {
pub fn new() -> Self {
Cursor{
dirty: false,
l_forest: Vec::new(),
tree: None,
r_forest: Vec::new(),
}
}
pub fn with_depth(depth: usize) -> Self {
Cursor{
dirty: false,
l_forest: Vec::with_capacity(depth),
tree: None,
r_forest: Vec::with_capacity(depth),
}
}
pub fn split(self) -> (Cursor<E>, Option<Tree<E>>, Cursor<E>) {
let (l_tree,r_tree) = match self.tree {
None => (None, None),
Some(ref t) => (t.l_tree(), t.r_tree())
};
(
Cursor{
dirty: true,
l_forest: self.l_forest,
tree: l_tree,
r_forest: Vec::with_capacity(DEFAULT_DEPTH),
},
self.tree,
Cursor{
dirty: true,
l_forest: Vec::with_capacity(DEFAULT_DEPTH),
tree: r_tree,
r_forest: self.r_forest,
},
)
}
pub fn into_iters(self) -> (IterL<E>,Option<Tree<E>>,IterR<E>) {
let (l_tree,r_tree) = match self.tree {
None => (None, None),
Some(ref t) => (t.l_tree(), t.r_tree())
};
let mut l_cursor = Cursor{
dirty: true,
l_forest: self.l_forest,
tree: l_tree,
r_forest: Vec::new(),
};
let mut r_cursor = Cursor{
dirty: true,
l_forest: Vec::new(),
tree: r_tree,
r_forest: self.r_forest,
};
if l_cursor.tree.is_none() { l_cursor.up_discard(); } else {
while l_cursor.down_right() {}
}
if r_cursor.tree.is_none() { r_cursor.up_discard(); } else {
while r_cursor.down_left() {}
}
(
IterL(l_cursor),
self.tree,
IterR(r_cursor),
)
}
pub fn join(mut l_cursor: Self, level: u32, name: Option<Name>, data: E, mut r_cursor: Self) -> Self {
while !l_cursor.r_forest.is_empty() { assert!(l_cursor.up() != UpResult::Fail); }
while !r_cursor.l_forest.is_empty() { assert!(r_cursor.up() != UpResult::Fail); }
while let Some(h) = l_cursor.up_left_level() {
if h >= level { break; }
else { assert!(l_cursor.up() != UpResult::Fail); }
}
while let Some(h) = l_cursor.peek_level() {
if h < level { break; }
else { assert!(l_cursor.down_right_force(Force::Yes)); }
}
while let Some(h) = r_cursor.up_right_level() {
if h > level { break; }
else { assert!(r_cursor.up() != UpResult::Fail); }
}
while let Some(h) = r_cursor.peek_level() {
if h <= level { break; }
else { assert!(r_cursor.down_left_force(Force::Yes)); }
}
let tree = Tree::new(
level, name.clone(),
E::rebuild(peek_op(&l_cursor.tree).as_ref(), &data, level, name, peek_op(&r_cursor.tree).as_ref()),
l_cursor.tree.clone(),
r_cursor.tree.clone(),
);
assert!(tree.is_some());
Cursor{
dirty: true,
l_forest: l_cursor.l_forest,
tree: tree,
r_forest: r_cursor.r_forest,
}
}
pub fn at_tree(&self) -> Option<Tree<E>> { self.tree.clone() }
pub fn left_tree(&self) -> Option<Tree<E>> {
match self.tree { None => None, Some(ref t) => t.l_tree() }
}
pub fn right_tree(&self) -> Option<Tree<E>> {
match self.tree { None => None, Some(ref t) => t.r_tree() }
}
pub fn peek(&self) -> Option<E> {
peek_op(&self.tree)
}
pub fn peek_level(&self) -> Option<u32> {
self.tree.as_ref().map(|t| t.level())
}
pub fn peek_name(&self) -> Option<Name> {
match self.tree {
None => None,
Some(ref t) => t.name()
}
}
fn up_left_level(&self) -> Option<u32> {
match self.l_forest.last() {
None => None,
Some(&(_,ref t)) => Some(t.level()),
}
}
fn up_right_level(&self) -> Option<u32> {
match self.r_forest.last() {
None => None,
Some(&(_,ref t)) => Some(t.level()),
}
}
pub fn down_left_force(&mut self, force: Force) -> bool {
let new_tree = match self.tree {
None => return false,
Some(ref t) => {
let lt = t.l_tree();
if lt.is_none() && force == Force::No { return false }
lt
}
};
let old_tree = mem::replace(&mut self.tree, new_tree).unwrap();
if force != Force::Discard {
self.r_forest.push((self.dirty, old_tree));
self.dirty = false;
} else { self.dirty = true; }
true
}
pub fn down_left(&mut self) -> bool { self.down_left_force(Force::No) }
pub fn down_right_force(&mut self, force: Force) -> bool {
let new_tree = match self.tree {
None => return false,
Some(ref t) => {
let rt = t.r_tree();
if rt.is_none() && force == Force::No { return false }
rt
}
};
let old_tree = mem::replace(&mut self.tree, new_tree).unwrap();
if force != Force::Discard {
self.l_forest.push((self.dirty, old_tree));
self.dirty = false;
} else { self.dirty = true; }
true
}
pub fn down_right(&mut self) -> bool { self.down_right_force(Force::No) }
pub fn up(&mut self) -> UpResult {
let to_left = match (self.l_forest.last(), self.r_forest.last()) {
(None, None) => { return UpResult::Fail },
(Some(_), None) => true,
(Some(&(_,ref lt)), Some(&(_,ref rt))) if rt.level() > lt.level() => true,
_ => false,
};
if to_left {
if let Some((dirty, upper_tree)) = self.l_forest.pop() {
if self.dirty == true {
let l_branch = upper_tree.l_tree();
self.tree = Tree::new(
upper_tree.level(), upper_tree.name(),
E::rebuild(peek_op(&l_branch).as_ref(), &upper_tree.peek(), upper_tree.level(), upper_tree.name(), peek_op(&self.tree).as_ref()),
l_branch,
self.tree.take(),
)
} else { self.dirty = dirty; self.tree = Some(upper_tree) }
} else { panic!("up: empty left forest item"); }
} else { if let Some((dirty, upper_tree)) = self.r_forest.pop() {
if self.dirty == true {
let r_branch = upper_tree.r_tree();
self.tree = Tree::new(
upper_tree.level(), upper_tree.name(),
E::rebuild(peek_op(&self.tree).as_ref(), &upper_tree.peek(), upper_tree.level(), upper_tree.name(), peek_op(&r_branch).as_ref()),
self.tree.take(),
r_branch,
)
} else { self.dirty = dirty; self.tree = Some(upper_tree) }
} else { panic!("up: empty right forest item"); }
}
return if to_left { UpResult::Left } else { UpResult::Right };
}
pub fn up_discard(&mut self) -> UpResult {
let to_left = match (self.l_forest.last(), self.r_forest.last()) {
(None, None) => { return UpResult::Fail },
(Some(_), None) => true,
(Some(&(_,ref lt)), Some(&(_,ref rt))) if rt.level() > lt.level() => true,
_ => false,
};
if to_left {
if let Some((dirty, upper_tree)) = self.l_forest.pop() {
self.dirty = dirty;
self.tree = Some(upper_tree);
} else { panic!("up: empty left forest item"); }
} else { if let Some((dirty, upper_tree)) = self.r_forest.pop() {
self.dirty = dirty;
self.tree = Some(upper_tree);
} else { panic!("up: empty right forest item"); }
}
return if to_left { UpResult::Left } else { UpResult::Right };
}
}
#[derive(Debug,Clone,PartialEq,Eq,Hash)]
pub struct IterL<T: TreeUpdate+Debug+Clone+Eq+Hash+'static>(Cursor<T>);
#[derive(Debug,Clone,Eq,PartialEq,Hash)]
pub struct IterR<T: TreeUpdate+Debug+Clone+Eq+Hash+'static>(Cursor<T>);
impl<T: TreeUpdate+Debug+Clone+Eq+Hash+'static> IterR<T> {
pub fn fold_out<R,B>(mut self, init: R, bin: Rc<B>) -> R where
R:'static + Eq+Clone+Hash+Debug,
B:'static + Fn(R,T) -> R
{
let name = self.0.peek_name();
match self.next() {
None => return init,
Some(e) => {
let a = bin(init,e);
match name {
None => self.fold_out(a,bin),
Some(n) => {
let (n,_) = name_fork(n);
let i = self;
memo!( n =>> Self::fold_out , i:i, a:a ;; f:bin.clone())
}
}
}
}
}
}
impl<T: TreeUpdate+Debug+Clone+Eq+Hash+'static>
Iterator for IterR<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let result = self.0.peek();
if self.0.down_right() {
while self.0.down_left() {};
} else { loop {
match self.0.up_discard() {
UpResult::Left => {},
UpResult::Right => { break },
UpResult::Fail => {
self.0 = Cursor::new();
break;
}
}
}}
return result;
}
}
#[cfg(test)]
mod tests {
use super::*;
impl DeriveTreeUpdate for usize {}
#[test]
fn test_movement() {
let t =
Tree::new(5, Some(name_of_usize(5)),1,
Tree::new(3, Some(name_of_usize(3)),2,
Tree::new(0,None,4,None,None),
Tree::new(2, Some(name_of_usize(2)),5,
Tree::new(1, Some(name_of_usize(1)),8,
Tree::new(0,None,10,None,None),
Tree::new(0,None,11,None,None),
),
Tree::new(0,None,9,None,None),
)
),
Tree::new(4, Some(name_of_usize(4)),3,
Tree::new(0,None,6,None,None),
Tree::new(0,None,7,None,None),
)
).unwrap();
let mut c: Cursor<usize> = t.into();
assert_eq!(Some(1), c.peek());
assert!(c.down_left());
assert!(c.down_right());
assert!(c.down_left());
assert!(c.down_right());
assert_eq!(Some(11), c.peek());
assert!(c.up() != UpResult::Fail);
assert!(c.up() != UpResult::Fail);
assert!(c.up() != UpResult::Fail);
assert_eq!(Some(2), c.peek());
assert!(c.down_left_force(Force::Discard));
assert_eq!(Some(4), c.peek());
assert!(c.up() != UpResult::Fail);
assert!(c.down_right());
assert!(c.down_right());
assert_eq!(Some(7), c.peek());
assert!(!c.down_right());
assert!(c.down_right_force(Force::Yes));
assert_eq!(None, c.peek());
}
#[test]
fn test_split_join() {
let t =
Tree::new(5, Some(name_of_usize(5)),1,
Tree::new(3, Some(name_of_usize(3)),2,
Tree::new(0,None,4,None,None),
Tree::new(2, Some(name_of_usize(2)),5,
Tree::new(1, Some(name_of_usize(1)),8,
Tree::new(0,None,10,None,None),
Tree::new(0,None,11,None,None),
),
Tree::new(0,None,9,None,None),
)
),
Tree::new(4, Some(name_of_usize(4)),3,
Tree::new(0,None,6,None,None),
Tree::new(0,None,7,None,None),
)
).unwrap();
let mut c: Cursor<usize> = t.into();
assert!(c.down_left());
let (mut lc, t, mut rc) = c.split();
assert_eq!(Some(4), lc.peek());
assert_eq!(Some(5), rc.peek());
assert!(lc.up() == UpResult::Fail);
assert!(rc.up() != UpResult::Fail);
assert_eq!(Some(1), rc.peek());
let t = t.unwrap();
let mut j = Cursor::join(rc, t.level(), t.name(), t.peek(), lc);
assert_eq!(Some(2), j.peek());
assert!(j.down_left());
assert_eq!(Some(7), j.peek());
assert!(j.up() != UpResult::Fail);
assert!(j.up() != UpResult::Fail);
assert_eq!(Some(3), j.peek());
}
#[test]
fn test_iter_r() {
let t =
Tree::new(5, Some(name_of_usize(5)),1,
Tree::new(3, Some(name_of_usize(3)),2,
Tree::new(0,None,4,None,None),
Tree::new(2, Some(name_of_usize(2)),5,
Tree::new(1, Some(name_of_usize(1)),8,
Tree::new(0,None,10,None,None),
Tree::new(0,None,11,None,None),
),
Tree::new(0,None,9,None,None),
)
),
Tree::new(4, Some(name_of_usize(4)),3,
Tree::new(0,None,6,None,None),
Tree::new(0,None,7,None,None),
)
).unwrap();
let mut c: Cursor<usize> = t.into();
assert!(c.down_left());
assert!(c.down_right());
assert!(c.down_left());
assert!(c.down_right());
let (_,t,iter) = c.into_iters();
assert_eq!(Some(11),t.map(|e|e.peek()));
let right = iter.collect::<Vec<_>>();
assert_eq!(vec![5,9,1,6,3,7], right);
}
}