1use std::fmt::{self, Display};
2
3#[derive(Debug)]
6pub struct Tree<D: Display>(D, Vec<Tree<D>>);
7
8impl<D: Display> Tree<D> {
9 pub fn new(root: D, leaves: Vec<Tree<D>>) -> Tree<D> {
10 Tree(root, leaves)
11 }
12
13 pub fn root(root: D) -> Tree<D> {
14 Tree(root, Vec::new())
15 }
16
17 pub fn push(&mut self, leaf: Tree<D>) -> &mut Self {
18 self.1.push(leaf);
19 self
20 }
21
22 fn display_leaves(f: &mut fmt::Formatter,
23 leaves: &Vec<Tree<D>>,
24 spaces: Vec<bool>)
25 -> fmt::Result {
26 for (i, leaf) in leaves.iter().enumerate() {
27 let last = i >= leaves.len() - 1;
28 let mut clone = spaces.clone();
29 for s in &spaces {
31 if *s {
32 let _ = write!(f, " ");
33 } else {
34 let _ = write!(f, "| ");
35 }
36 }
37 if last {
38 let _ = writeln!(f, "└── {}", leaf.0);
39 } else {
40 let _ = writeln!(f, "├── {}", leaf.0);
41 }
42
43 if !leaf.1.is_empty() {
45 clone.push(last);
46 let _ = Self::display_leaves(f, &leaf.1, clone);
47 }
48 }
49 write!(f, "")
50 }
51}
52
53impl<D: Display> Display for Tree<D> {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 let _ = writeln!(f, "{}", self.0);
56 Self::display_leaves(f, &self.1, Vec::new())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::Tree;
63 #[test]
64 fn render_tree_root() {
65 let tree = Tree::root("foo");
66 assert_eq!(format!("{}", tree), "foo\n")
67 }
68
69 #[test]
70 fn render_tree_with_leaves() {
71 let tree = Tree::new(
72 "foo", vec![
73 Tree::new(
74 "bar", vec![
75 Tree::root("baz")
76 ]
77 )
78 ]
79 );
80 assert_eq!(format!("{}", tree), r#"foo
81└── bar
82 └── baz
83"#)
84 }
85}