orx_tree/common_traits/display.rs
1use crate::{
2 Dfs, MemoryPolicy, Node, NodeMut, NodeRef, Traversal, Traverser, Tree, TreeVariant,
3 pinned_storage::PinnedStorage, traversal::OverDepthSiblingIdxNode,
4};
5use alloc::string::ToString;
6use alloc::vec::Vec;
7use core::fmt::Display;
8
9impl<V, M, P> Display for Node<'_, V, M, P>
10where
11 V: TreeVariant,
12 M: MemoryPolicy,
13 P: PinnedStorage,
14 V::Item: Display,
15{
16 /// Creates a convenient-to-read string representation of the tree or a subtree rooted at a node.
17 ///
18 /// # Examples
19 ///
20 /// ```
21 /// use orx_tree::*;
22 ///
23 /// // 1
24 /// // ╱ ╲
25 /// // ╱ ╲
26 /// // 2 3
27 /// // ╱ ╲ ╱ ╲
28 /// // 4 5 6 7
29 /// // | | ╱ ╲
30 /// // 8 9 10 11
31 ///
32 /// let mut tree = DynTree::new(1);
33 ///
34 /// let mut root = tree.root_mut();
35 /// let [id2, id3] = root.push_children([2, 3]);
36 /// let [id4, _] = tree.node_mut(&id2).push_children([4, 5]);
37 /// tree.node_mut(&id4).push_child(8);
38 /// let [id6, id7] = tree.node_mut(&id3).push_children([6, 7]);
39 /// tree.node_mut(&id6).push_child(9);
40 /// tree.node_mut(&id7).push_children([10, 11]);
41 ///
42 /// let expected_str = r#"1
43 /// ├──2
44 /// │ ├──4
45 /// │ │ └──8
46 /// │ └──5
47 /// └──3
48 /// ├──6
49 /// │ └──9
50 /// └──7
51 /// ├──10
52 /// └──11
53 /// "#;
54 /// assert_eq!(tree.to_string(), expected_str);
55 ///
56 /// let expected_str = r#"3
57 /// ├──6
58 /// │ └──9
59 /// └──7
60 /// ├──10
61 /// └──11
62 /// "#;
63 /// println!("{}", tree.node(&id3).to_string());
64 /// assert_eq!(tree.node(&id3).to_string(), expected_str);
65 /// ```
66 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67 let mut t = Traversal.dfs().over_nodes().with_depth().with_sibling_idx();
68 display_node(f, self, &mut t)
69 }
70}
71
72impl<V, M, P> Display for NodeMut<'_, V, M, P>
73where
74 V: TreeVariant,
75 M: MemoryPolicy,
76 P: PinnedStorage,
77 V::Item: Display,
78{
79 /// Creates a convenient-to-read string representation of the tree or a subtree rooted at a node.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// use orx_tree::*;
85 ///
86 /// // 1
87 /// // ╱ ╲
88 /// // ╱ ╲
89 /// // 2 3
90 /// // ╱ ╲ ╱ ╲
91 /// // 4 5 6 7
92 /// // | | ╱ ╲
93 /// // 8 9 10 11
94 ///
95 /// let mut tree = DynTree::new(1);
96 ///
97 /// let mut root = tree.root_mut();
98 /// let [id2, id3] = root.push_children([2, 3]);
99 /// let [id4, _] = tree.node_mut(&id2).push_children([4, 5]);
100 /// tree.node_mut(&id4).push_child(8);
101 /// let [id6, id7] = tree.node_mut(&id3).push_children([6, 7]);
102 /// tree.node_mut(&id6).push_child(9);
103 /// tree.node_mut(&id7).push_children([10, 11]);
104 ///
105 /// let expected_str = r#"1
106 /// ├──2
107 /// │ ├──4
108 /// │ │ └──8
109 /// │ └──5
110 /// └──3
111 /// ├──6
112 /// │ └──9
113 /// └──7
114 /// ├──10
115 /// └──11
116 /// "#;
117 /// assert_eq!(tree.to_string(), expected_str);
118 ///
119 /// let expected_str = r#"3
120 /// ├──6
121 /// │ └──9
122 /// └──7
123 /// ├──10
124 /// └──11
125 /// "#;
126 /// println!("{}", tree.node(&id3).to_string());
127 /// assert_eq!(tree.node(&id3).to_string(), expected_str);
128 /// ```
129 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
130 let mut t = Traversal.dfs().over_nodes().with_depth().with_sibling_idx();
131 display_node(f, self, &mut t)
132 }
133}
134
135impl<V, M, P> Display for Tree<V, M, P>
136where
137 V: TreeVariant,
138 M: MemoryPolicy,
139 P: PinnedStorage,
140 V::Item: Display,
141{
142 /// Creates a convenient-to-read string representation of the tree or a subtree rooted at a node.
143 ///
144 /// # Examples
145 ///
146 /// ```
147 /// use orx_tree::*;
148 ///
149 /// // 1
150 /// // ╱ ╲
151 /// // ╱ ╲
152 /// // 2 3
153 /// // ╱ ╲ ╱ ╲
154 /// // 4 5 6 7
155 /// // | | ╱ ╲
156 /// // 8 9 10 11
157 ///
158 /// let mut tree = DynTree::new(1);
159 ///
160 /// let mut root = tree.root_mut();
161 /// let [id2, id3] = root.push_children([2, 3]);
162 /// let [id4, _] = tree.node_mut(&id2).push_children([4, 5]);
163 /// tree.node_mut(&id4).push_child(8);
164 /// let [id6, id7] = tree.node_mut(&id3).push_children([6, 7]);
165 /// tree.node_mut(&id6).push_child(9);
166 /// tree.node_mut(&id7).push_children([10, 11]);
167 ///
168 /// let expected_str = r#"1
169 /// ├──2
170 /// │ ├──4
171 /// │ │ └──8
172 /// │ └──5
173 /// └──3
174 /// ├──6
175 /// │ └──9
176 /// └──7
177 /// ├──10
178 /// └──11
179 /// "#;
180 /// assert_eq!(tree.to_string(), expected_str);
181 ///
182 /// let expected_str = r#"3
183 /// ├──6
184 /// │ └──9
185 /// └──7
186 /// ├──10
187 /// └──11
188 /// "#;
189 /// println!("{}", tree.node(&id3).to_string());
190 /// assert_eq!(tree.node(&id3).to_string(), expected_str);
191 /// ```
192 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
193 match self.get_root() {
194 Some(root) => {
195 let mut t = Traversal.dfs().over_nodes().with_depth().with_sibling_idx();
196 display_node(f, &root, &mut t)
197 }
198 None => Ok(()),
199 }
200 }
201}
202
203fn display_node<'a, V, M, P>(
204 f: &mut core::fmt::Formatter<'_>,
205 node: &'a impl NodeRef<'a, V, M, P>,
206 t: &'a mut Dfs<OverDepthSiblingIdxNode>,
207) -> core::fmt::Result
208where
209 V: TreeVariant + 'a,
210 M: MemoryPolicy,
211 P: PinnedStorage,
212 V::Item: Display,
213{
214 fn set_depth(depths: &mut Vec<bool>, depth: usize, continues: bool) {
215 match depth < depths.len() {
216 true => depths[depth] = continues,
217 false => depths.push(continues),
218 }
219 }
220
221 let mut depths: Vec<bool> = Default::default();
222 let mut iter = node.walk_with(t);
223
224 if let Some((_, _, root)) = iter.next() {
225 writeln!(f, "{}", root.data().to_string().as_str())?;
226 set_depth(&mut depths, 0, true);
227
228 for (depth, sibling_idx, node) in iter {
229 let is_last_sibling = node.num_siblings() == sibling_idx + 1;
230
231 set_depth(&mut depths, depth, true);
232 set_depth(&mut depths, depth - 1, !is_last_sibling);
233
234 for d in depths.iter().take(depth - 1) {
235 match d {
236 true => write!(f, "│")?,
237 false => write!(f, " ")?,
238 }
239 write!(f, " ")?;
240 }
241
242 let first_depth_char = match is_last_sibling {
243 true => 'â””',
244 false => '├',
245 };
246
247 write!(f, "{}", first_depth_char)?;
248 write!(f, "──")?;
249
250 writeln!(f, "{}", node.data().to_string().as_str())?;
251 }
252 }
253
254 Ok(())
255}