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
use std::fmt::{self, Display};
#[derive(Debug)]
pub struct Tree<D: Display>(D, Vec<Tree<D>>);
impl<D: Display> Tree<D> {
pub fn new(root: D, leaves: Vec<Tree<D>>) -> Tree<D> {
Tree(root, leaves)
}
pub fn root(root: D) -> Tree<D> {
Tree(root, Vec::new())
}
pub fn push(&mut self, leaf: Tree<D>) -> &mut Self {
self.1.push(leaf);
self
}
fn display_leaves(f: &mut fmt::Formatter,
leaves: &Vec<Tree<D>>,
spaces: Vec<bool>)
-> fmt::Result {
for (i, leaf) in leaves.iter().enumerate() {
let last = i >= leaves.len() - 1;
let mut clone = spaces.clone();
for s in &spaces {
if *s {
let _ = write!(f, " ");
} else {
let _ = write!(f, "| ");
}
}
if last {
let _ = writeln!(f, "└── {}", leaf.0);
} else {
let _ = writeln!(f, "├── {}", leaf.0);
}
if !leaf.1.is_empty() {
clone.push(last);
let _ = Self::display_leaves(f, &leaf.1, clone);
}
}
write!(f, "")
}
}
impl<D: Display> Display for Tree<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let _ = writeln!(f, "{}", self.0);
Self::display_leaves(f, &self.1, Vec::new())
}
}
#[cfg(test)]
mod tests {
use super::Tree;
#[test]
fn render_tree_root() {
let tree = Tree::root("foo");
assert_eq!(format!("{}", tree), "foo\n")
}
#[test]
fn render_tree_with_leaves() {
let tree = Tree::new(
"foo", vec![
Tree::new(
"bar", vec![
Tree::root("baz")
]
)
]
);
assert_eq!(format!("{}", tree), r#"foo
└── bar
└── baz
"#)
}
}