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}