1use std::fmt::{Display, Formatter, Result};
11
12const INDENT_FREE: &str = "│ ";
13const INDENT_NODE: &str = "├── ";
14const INDENT_END: &str = "└── ";
15const INDENT_EMPTY: &str = " ";
16
17#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
18pub struct Node {
19 pub node: String,
20 pub children: Vec<Node>,
21}
22
23pub trait ToTreeView {
24 fn to_node(&self) -> Node;
25}
26
27#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
28pub struct TreeView<'a, T>
29where
30 T: ToTreeView,
31{
32 pub original: &'a T,
33 pub root: Node,
34}
35
36#[allow(unused)]
37impl Node {
38 pub fn new() -> Self {
39 Node {
40 node: String::from(""),
41 children: Vec::new(),
42 }
43 }
44
45 pub fn from(n: Node) -> Self {
46 Node {
47 node: n.node,
48 children: n.children,
49 }
50 }
51
52 pub fn insert(mut self, n: Node) {
53 self.children.push(n);
54 }
55
56 pub fn print_node(self, pre: &str, first: bool, last: bool) -> String {
57 let node: &str = self.node.as_str();
58 let n = self.children.len();
59
60 let mut output: String = String::from("");
61 let mut pre: String = String::from(pre);
62
63 if last {
64 output = format!("{pre}{INDENT_END}") + node + "\n";
65 pre = format!("{pre}{INDENT_EMPTY}");
66 } else if first {
67 output = output + node + "\n";
68 } else {
69 output = format!("{pre}{INDENT_NODE}") + node + "\n";
70 pre = format!("{pre}{INDENT_FREE}");
71 }
72
73 for (i, c) in self.children.into_iter().enumerate() {
75 output = output + &c.print_node(pre.as_str(), false, i == n - 1);
76 }
77
78 output
79 }
80}
81
82impl Default for Node {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl<'a, T> TreeView<'a, T>
89where
90 T: Ord + ToTreeView,
91{
92 pub fn new(t: &'a T) -> Self {
93 TreeView {
94 original: t,
95 root: t.to_node(),
96 }
97 }
98
99 pub fn print(self) -> String {
100 self.root.print_node("", true, false)
101 }
102}
103
104impl<T> Display for TreeView<'_, T>
105where
106 T: Ord + ToTreeView,
107{
108 fn fmt(&self, f: &mut Formatter) -> Result {
109 let output = self.root.clone().print_node("", true, false);
110 write!(f, "{}", output)
111 }
112}