Skip to main content

xtree/
cursor.rs

1use crate::tree::Tree;
2use std::marker::PhantomData;
3use crate::children_iter::{ChildrenIter, ChildrenIterMut};
4
5/// A immutable Cursor can freely visit node in tree
6pub struct Cursor<'a,T> {
7    pub (in crate) root : &'a Tree<T>,
8    pub (in crate) parents : Vec<&'a Tree<T>>,
9    pub (in crate) now : &'a Tree<T>,
10}
11
12impl<'a,T> Cursor<'a,T> {
13    /// Move this cursor to the specified child
14    /// # Panics
15    /// Panics if 'at' >= children_count()
16    pub fn move_child(&mut self,at : usize){
17        if at < self.children_count() {
18            self.parents.push(self.now);
19            self.now = self.now.children.get(at).unwrap();//no failure
20        }else{
21            panic!("Cursor::move_child(): index {} is out of children's length",at);
22        }
23    }
24
25    /// move this cursor to its parent.
26    /// Do nothing if it is already in the root node.
27    pub fn move_parent(&mut self){
28        if let Some(parent) = self.parents.pop(){
29            self.now = parent;
30        }
31    }
32
33    /// Move this cursor to its root.
34    /// Do nothing if it is already in the root node.
35    pub fn move_root(&mut self){
36        self.now = self.root;
37        self.parents.clear();
38    }
39
40    /// Return the reference to the current
41    pub fn current(&self) -> &'a T {
42        &self.now.data
43    }
44
45    /// Get the count of children in current node
46    pub fn children_count(&self) -> usize {
47        self.now.children.len()
48    }
49
50    /// Get a immutable children iterator
51    pub fn children(&self) -> ChildrenIter<'a,T>{
52        ChildrenIter{
53            raw_iter: self.now.children.iter()
54        }
55    }
56
57    /// Return true if current node is the root
58    pub fn is_root(&self) -> bool {
59        self.parents.is_empty()
60    }
61
62    /// Return true if current node is a leaf
63    pub fn is_leaf(&self) -> bool {
64        self.now.children.is_empty()
65    }
66}
67
68
69/// A mutable Cursor can freely visit node in tree
70pub struct CursorMut<'a,T>{
71    pub (in crate) root : *mut Tree<T>,
72    pub (in crate) parents : Vec<*mut Tree<T>>,
73    pub (in crate) now : *mut Tree<T>,
74    pub (in crate) _marker : PhantomData<&'a T>
75}
76
77impl<'a,T> CursorMut<'a,T>{
78    /// Move this cursor to the specified child
79    /// # Panics
80    /// Panics if 'at' >= children_count()
81    pub fn move_child(&mut self,at : usize){
82        if at < self.children_count() {
83            self.parents.push(self.now);
84            self.now = unsafe{&mut *self.now}.children.get_mut(at).unwrap();//no failure
85        }else{
86            panic!("CursorMut::move_child(): index {} is out of children's length",at);
87        }
88    }
89
90    /// move this cursor to its parent.
91    /// Do nothing if it is already in the root node.
92    pub fn move_parent(&mut self){
93        if let Some(parent) = self.parents.pop(){
94            self.now = parent;
95        }
96    }
97
98    /// Move this cursor to its root.
99    /// Do nothing if it is already in the root node.
100    pub fn move_root(&mut self){
101        self.now = self.root;
102        self.parents.clear();
103    }
104
105    /// Return the reference to the current
106    pub fn current(&self) -> &'a mut T {
107        &mut unsafe{&mut *self.now}.data
108    }
109
110    /// Get the count of children in current node
111    pub fn children_count(&self) -> usize {
112        unsafe{&*self.now}.children.len()
113    }
114
115    /// Get a immutable children iterator
116    pub fn children(&self) -> ChildrenIterMut<'a,T>{
117        ChildrenIterMut{
118            raw_iter: unsafe{&mut *self.now}.children.iter_mut()
119        }
120    }
121
122    /// Return true if current node is the root
123    pub fn is_root(&self) -> bool {
124        self.parents.is_empty()
125    }
126
127    /// Return true if current node is a leaf
128    pub fn is_leaf(&self) -> bool {
129        unsafe{&*self.now}.children.is_empty()
130    }
131
132    /// Remove a sub-tree and consume the cursor<br>
133    /// return None when current node is root
134    pub fn remove(self) -> Option<Tree<T>>{
135        if self.is_root() {
136            Option::None
137        }else{
138            let parent = unsafe{&mut **self.parents.last().unwrap()};
139            let mut index = 0;
140            for (i,ptr) in parent.children.iter().enumerate() {
141                if (ptr as *const _) == self.now {
142                    index = i;
143                    break;
144                }
145            }
146            Option::Some(parent.children.remove(index))
147        }
148    }
149
150    /// Add a sub-tree to children of current node
151    pub fn add_child(&mut self,tree : Tree<T>){
152        unsafe{&mut *self.now}.children.push(tree);
153    }
154
155}