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