1use crate::fn_filestree::FileNode;
2use colored::*;
3
4#[derive(Debug, Clone)]
6pub struct TreeStyle {
7 pub dir_last_with_children: String, pub dir_last_no_children: String, pub dir_mid_with_children: String, pub dir_mid_no_children: String, pub file_last: String, pub file_mid: String, pub indent_last: String, pub indent_mid: String, }
21
22impl Default for TreeStyle {
23 fn default() -> Self {
24 Self {
25 dir_last_with_children: "└──┬".to_string(),
26 dir_last_no_children: "└───".to_string(),
27 dir_mid_with_children: "├──┬".to_string(),
28 dir_mid_no_children: "├───".to_string(),
29
30 file_last: "└──•".to_string(),
31 file_mid: "├──•".to_string(),
32
33 indent_last: " ".to_string(),
34 indent_mid: "│ ".to_string(),
35 }
36 }
37}
38
39
40fn plot(nodes: &[FileNode], indent: &str, s: &TreeStyle, use_color: bool) -> String {
42 let mut result = String::new();
43
44 for (i, node) in nodes.iter().enumerate() {
45 let is_last = i == nodes.len() - 1;
46 let has_children = !node.children.is_empty();
47
48 let branch = if node.is_dir {
50 match (is_last, has_children) {
51 (true, true) => &s.dir_last_with_children,
52 (false, true) => &s.dir_mid_with_children,
53 (true, false) => &s.dir_last_no_children,
54 (false, false) => &s.dir_mid_no_children,
55 }
56 } else if is_last {
57 &s.file_last
58 } else {
59 &s.file_mid
60 };
61
62 let line = if use_color {
64 if node.is_dir {
65 format!("{}{} {}{}/\n", indent.green(), branch.green(), node.icon, node.name.truecolor(200, 200, 50))
66 } else {
67 format!("{}{} {}{}\n", indent.green(), branch.green(), node.icon, node.name.white())
68 }
69 } else {
70 format!("{}{} {} {}\n", indent, branch, node.icon, node.name)
71 };
72
73 result.push_str(&line);
74
75 if has_children {
77 let new_indent = if is_last {
78 format!("{}{}", indent, s.indent_last)
79 } else {
80 format!("{}{}", indent, s.indent_mid)
81 };
82 result.push_str(&plot(&node.children, &new_indent, s, use_color));
83 }
84 }
85
86 result
87}
88
89pub fn plotfiles_txt(nodes: &[FileNode], indent: &str, style: Option<&TreeStyle>) -> String {
91 let default_style = TreeStyle::default();
92 let s = style.unwrap_or(&default_style);
93
94 plot(nodes, indent, s, false)
95}
96
97pub fn plotfiles_cli(nodes: &[FileNode], indent: &str, style: Option<&TreeStyle>) -> String {
99 let default_style = TreeStyle::default();
100 let s = style.unwrap_or(&default_style);
101
102 plot(nodes, indent, s, true)
103}