1use std::vec;
2
3pub mod implementations;
4
5pub trait DisplayableNode: Sized {
7 fn label(&self) -> Option<String>;
8 fn children(&self) -> Vec<&Self>;
9
10 fn display(&self) -> String {
11 NodeDisplayBlock::from_displayable_node(self, 0).extract()
12 }
13}
14
15struct NodeDisplayBlock {
17 lines: Vec<String>,
18}
19
20impl NodeDisplayBlock {
21 fn extract(self) -> String {
22 self.lines.join("\n")
23 }
24
25 fn from_displayable_node<N: DisplayableNode>(node: &N, index: usize) -> Self {
26 let mut result = Self::from_label(node, index);
27 let children = node.children();
28 result.append_children::<N>(children);
29
30 result
31 }
32
33 fn from_label<N: DisplayableNode>(node: &N, index: usize) -> Self {
34 let mut lines = Vec::new();
35 let label = node.label().unwrap_or_else(|| format!("[{index}]"));
36
37 for line in label.lines() {
38 lines.push(line.to_string());
39 }
40
41 Self { lines }
42 }
43
44 fn append_children<N: DisplayableNode>(&mut self, children: Vec<&N>) {
45 if children.is_empty() {
46 return;
47 }
48 let last_child_index = children.len() - 1;
49 let mut children_iterator = children.into_iter();
50 self.append_middle_children_nodes(&mut children_iterator, last_child_index);
51 let last_child_node = children_iterator.next().unwrap();
52 self.append_last_child_node(last_child_node, last_child_index);
53 }
54
55 fn append_middle_children_nodes<N: DisplayableNode>(
56 &mut self,
57 children_iterator: &mut vec::IntoIter<&N>,
58 last_child_index: usize,
59 ) {
60 for middle_child_index in 0..last_child_index {
61 let middle_child_node = children_iterator.next().unwrap();
62 let middle_child_block =
63 Self::from_displayable_node(middle_child_node, middle_child_index);
64 self.append_middle_child_block(&middle_child_block);
65 }
66 }
67
68 fn append_last_child_node<N: DisplayableNode>(
69 &mut self,
70 last_child_node: &N,
71 last_child_index: usize,
72 ) {
73 let last_child_block = Self::from_displayable_node(last_child_node, last_child_index);
74 self.append_last_child_block(&last_child_block);
75 }
76
77 fn append_middle_child_block(&mut self, middle_child: &NodeDisplayBlock) {
78 let own_lines = &mut self.lines;
79 let mut child_lines_iterator = middle_child.lines.iter();
80 let child_label_line = child_lines_iterator.next().unwrap();
81 own_lines.push(format!("├─ {child_label_line}"));
82 for child_line in child_lines_iterator {
83 own_lines.push(format!("│ {child_line}"));
84 }
85 }
86
87 fn append_last_child_block(&mut self, last_child: &NodeDisplayBlock) {
88 let own_lines = &mut self.lines;
89 let mut child_lines_iterator = last_child.lines.iter();
90 let child_label_line = child_lines_iterator.next().unwrap();
91 own_lines.push(format!("└─ {child_label_line}"));
92 for child_line in child_lines_iterator {
93 own_lines.push(format!(" {child_line}"));
94 }
95 }
96}