1use std::collections::VecDeque;
4use crate::interface;
5use crate::Tree;
6use crate::tree::{self, NodeId};
7
8pub trait TreeHelper {
10 fn get_element (&self, node_id : &NodeId) -> &interface::Element;
11 fn get_element_mut (&mut self, node_id : &NodeId) -> &mut interface::Element;
12 fn get_parent (&self, child : &NodeId) -> &interface::Element;
13 fn get_parent_mut (&mut self, child : &NodeId) -> &mut interface::Element;
14 fn get_parent_id (&self, child : &NodeId) -> &NodeId;
15 fn splice_subtree (
18 &mut self,
19 parent_id : &NodeId,
20 other : &Tree <interface::Element>,
21 other_id : &NodeId,
22 order : interface::CreateOrder
23 ) -> NodeId;
24 fn write_formatted_names <W : std::fmt::Write> (&self, w : &mut W)
27 -> std::fmt::Result;
28}
29
30pub fn map_tree <T, U, F> (tree : &Tree <T>, f : F) -> Tree <U> where
32 F : Fn (&T) -> U
33{
34 use tree::{InsertBehavior, Node};
35 let mut out = Tree::new();
36 if let Some (root_id) = tree.root_node_id() {
37 let root = tree.get (root_id).unwrap();
38 let new_root_id = out
39 .insert (Node::new (f (root.data())), InsertBehavior::AsRoot).unwrap();
40 let mut parent_child_ids = root.children().iter()
41 .map (|child_id| (new_root_id.clone(), child_id.clone()))
42 .collect::<VecDeque <_>>();
43 while let Some ((new_parent_id, old_child_id)) =
44 parent_child_ids.pop_front()
45 {
46 let child = tree.get (&old_child_id).unwrap();
47 let new_child_id = out.insert (
48 Node::new (f (child.data())),
49 InsertBehavior::UnderNode (&new_parent_id)
50 ).unwrap();
51 for child_id in child.children().iter() {
52 parent_child_ids.push_back ((new_child_id.clone(), child_id.clone()));
53 }
54 }
55 }
56 out
57}
58
59impl TreeHelper for Tree <interface::Element> {
60 #[inline]
64 fn get_element (&self, node_id : &NodeId) -> &interface::Element {
65 self.get (node_id).unwrap().data()
66 }
67
68 #[inline]
72 fn get_element_mut (&mut self, node_id : &NodeId) -> &mut interface::Element {
73 self.get_mut (node_id).unwrap().data_mut()
74 }
75
76 #[inline]
81 fn get_parent (&self, child : &NodeId) -> &interface::Element {
82 self.get_element (self.get_parent_id (child))
83 }
84
85 #[inline]
90 fn get_parent_mut (&mut self, child : &NodeId) -> &mut interface::Element {
91 let parent_id = self.get_parent_id (child).clone();
92 self.get_element_mut (&parent_id)
93 }
94
95 #[inline]
100 fn get_parent_id (&self, child : &NodeId) -> &NodeId {
101 self.get (child).unwrap().parent().unwrap()
102 }
103
104 fn splice_subtree (
107 &mut self,
108 parent_id : &NodeId,
109 other : &Tree <interface::Element>,
110 other_id : &NodeId,
111 order : interface::CreateOrder
112 ) -> NodeId {
113 use tree::Node;
114 use interface::CreateOrder;
115 let subtree_root = Node::new (other.get_element (&other_id).clone());
116 let subtree_id = self.insert (
117 subtree_root, tree::InsertBehavior::UnderNode (parent_id)
118 ).unwrap();
119 match order {
120 CreateOrder::Append => {}
121 CreateOrder::Prepend => {
122 let _ = self.make_first_sibling (&subtree_id).unwrap();
123 }
124 CreateOrder::NthSibling (n) => {
125 let _ = self.make_nth_sibling (&subtree_id, n as usize).unwrap();
126 }
127 }
128 for child_id in other.children_ids (other_id).unwrap() {
129 self.splice_subtree (&subtree_id, other, child_id, CreateOrder::Append);
130 }
131 subtree_id
132 }
133
134 fn write_formatted_names<W: std::fmt::Write>(&self, w: &mut W)
135 -> std::fmt::Result
136 {
137 if let Some(node_id) = self.root_node_id() {
138 let childn = 0;
139 let level = 0;
140 let last = vec![];
141 let mut stack = vec![(node_id, childn, level, last)];
142 while let Some((node_id, childn, level, last)) = stack.pop() {
143 debug_assert_eq!(
144 last.len(), level,
145 "each previous level should indicate whether it has reached the last node"
146 );
147 let node = self.get(node_id)
148 .expect("getting node of existing node ref id");
149 if childn == 0 {
150 for i in 1..level {
151 if last[i - 1] {
152 write!(w, " ")?;
153 } else {
154 write!(w, "│ ")?;
155 }
156 }
157 if level > 0 {
158 if last[level - 1] {
159 write!(w, "└── ")?;
160 } else {
161 write!(w, "├── ")?;
162 }
163 }
164 let data = node.data();
165 let state = match data.controller.state {
166 interface::controller::State::Focused => "*",
167 interface::controller::State::Enabled => "",
168 interface::controller::State::Disabled => "†"
169 };
170 writeln!(w, "{}{}", data.name, state)?;
171 }
172 let mut children = node.children().iter().skip(childn);
173 if let Some(child_id) = children.next() {
174 let mut next_last = last.clone();
175 if children.next().is_some() {
176 stack.push((node_id, childn + 1, level, last));
177 next_last.push(false);
178 } else {
179 next_last.push(true);
180 }
181 stack.push((child_id, 0, level + 1, next_last));
182 }
183 }
184 }
185 Ok(())
186 }
187}
188
189#[cfg(test)]
190mod tests {
191 use crate::tree::{InsertBehavior, Node};
192 use super::*;
193 #[test]
194 fn test_map_tree() {
195 let mut tree = Tree::new();
196 let root_id = tree.insert (Node::new (0u32), InsertBehavior::AsRoot)
197 .unwrap();
198 let child_id = tree
199 .insert (Node::new (1), InsertBehavior::UnderNode (&root_id)).unwrap();
200 tree.insert (Node::new (2), InsertBehavior::UnderNode (&root_id)).unwrap();
201 tree.insert (Node::new (3), InsertBehavior::UnderNode (&child_id)).unwrap();
202 tree.insert (Node::new (4), InsertBehavior::UnderNode (&child_id)).unwrap();
203 let mut s = String::new();
204 tree.write_formatted (&mut s).unwrap();
205 println!("old tree:\n{}", s);
206 let new_tree : Tree <String> = map_tree (&tree, |i| (*i).to_string());
207 let mut s = String::new();
208 new_tree.write_formatted (&mut s).unwrap();
209 println!("new tree:\n{}", s);
210 }
211}