flange_flat_tree/navigator/builder.rs
1use super::navigator_impl::Navigator;
2use super::neighbors::Neighbors;
3
4/** Create a FlatTree using simple commands
5A flat tree itself is immutable, so we use the builder pattern.
6## Example
7
8```
9use flange_flat_tree::navigator::Builder;
10
11// A navigator just stores neigbors, so we provide no values
12let mut b = Builder::default();
13let root = b.start_element();
14let child = b.start_end_element();
15
16let nav = b.build();
17
18assert_eq!(nav.children(root), [child]);
19assert_eq!(nav.parent(child), Some(root));
20```
21 */
22pub struct Builder {
23 // current_depth: usize,
24
25 // List of the parents at the different levels (so the last one is always
26 // the current parent).
27 parents_stack: Vec<usize>,
28 // The last sibling for our current position (if any).
29 last_sibling: Option<usize>,
30
31 // Internal data for the final tree.
32 cur_neighbors: Vec<Neighbors<usize>>,
33}
34
35impl Default for Builder {
36 /// Create a new builder
37 fn default() -> Builder {
38 Builder {
39 cur_neighbors: Vec::new(),
40 // current_depth: 0,
41 parents_stack: Vec::new(),
42 last_sibling: None,
43 }
44 }
45}
46
47impl Builder {
48 /// Create a new builder and pre-allocate memory
49 pub fn with_capacity(c: usize) -> Builder {
50 Builder {
51 cur_neighbors: Vec::with_capacity(c),
52 // current_depth: 0,
53 parents_stack: Vec::new(),
54 last_sibling: None,
55 }
56 }
57
58 /** Start a new element.
59 *
60 * This element will be the child of the last element
61 * that was not finished with `end_element`.
62 */
63 pub fn start_element(&mut self) -> usize {
64 let my_index = self.cur_neighbors.len();
65 self.cur_neighbors.push(Neighbors {
66 me: Some(my_index),
67 parent: self.parents_stack.last().cloned(),
68 first_child: None,
69 next_sibling: None,
70 prev_sibling: self.last_sibling,
71 });
72 // Update last sibling
73 if let Some(ls) = self.last_sibling {
74 self.cur_neighbors[ls].next_sibling = Some(my_index);
75 }
76 // Update parent
77 if let Some(&parent_index) = self.parents_stack.last() {
78 if self.cur_neighbors[parent_index].first_child.is_none() {
79 self.cur_neighbors[parent_index].first_child = Some(my_index);
80 }
81 }
82 // Update state
83 self.parents_stack.push(my_index);
84 self.last_sibling = None;
85 my_index
86 }
87
88 /** End and element.
89 *
90 * No more children will be added to this element.
91 * The next element would be a sibling of this element.
92 */
93 pub fn end_element(&mut self) -> usize {
94 self.last_sibling = self.parents_stack.pop();
95 self.last_sibling.unwrap()
96 }
97
98 /** Start and imidiatly end an element.
99 *
100 * This is the same as calling `start_element` and `end_element`
101 * after each other.
102 */
103 pub fn start_end_element(&mut self) -> usize {
104 let my_index = self.cur_neighbors.len();
105 self.cur_neighbors.push(Neighbors {
106 me: Some(my_index),
107 first_child: None,
108 parent: self.parents_stack.last().cloned(),
109 next_sibling: None,
110 prev_sibling: self.last_sibling,
111 });
112 // Update last sibling
113 if let Some(ls) = self.last_sibling {
114 self.cur_neighbors[ls].next_sibling = Some(my_index);
115 }
116 // Update parent
117 if let Some(&parent_index) = self.parents_stack.last() {
118 if self.cur_neighbors[parent_index].first_child.is_none() {
119 self.cur_neighbors[parent_index].first_child = Some(my_index);
120 }
121 }
122 // Update state
123 self.last_sibling = Some(my_index);
124 my_index
125 }
126
127 /** Finish the building and create the `Navigator`.
128 *
129 * The navigator will be created and the buidler destructed.
130 */
131 pub fn build(self) -> Navigator {
132 Navigator::new(self.cur_neighbors)
133 }
134}