1use crate::fn_filestree::FileNode;
3use colored::*;
4
5#[derive(Debug, Clone)]
7pub struct TreeStyle {
8 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, }
22
23impl Default for TreeStyle {
24 fn default() -> Self {
25 Self {
26 dir_last_with_children: "└──┬".to_string(),
27 dir_last_no_children: "└───".to_string(),
28 dir_mid_with_children: "├──┬".to_string(),
29 dir_mid_no_children: "├───".to_string(),
30
31 file_last: "└──•".to_string(),
32 file_mid: "├──•".to_string(),
33
34 indent_last: " ".to_string(),
35 indent_mid: "│ ".to_string(),
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 weight_prefix = if node.weight_str.is_empty() {
64 String::new()
65 } else if use_color {
66 node.weight_str.truecolor(120, 120, 120).to_string()
68 } else {
69 node.weight_str.clone()
70 };
71
72 let line = if use_color {
74 if node.is_dir {
75 format!(
76 "{}{}{} {}{}/\n",
77 weight_prefix, indent.green(),
79 branch.green(),
80 node.icon,
81 node.name.truecolor(200, 200, 50)
82 )
83 } else {
84 format!(
85 "{}{}{} {}{}\n",
86 weight_prefix, indent.green(),
88 branch.green(),
89 node.icon,
90 node.name.white()
91 )
92 }
93 } else {
94 format!(
96 "{}{}{} {} {}\n",
97 weight_prefix, indent, branch, node.icon, node.name
98 )
99 };
100
101 result.push_str(&line);
102
103 if has_children {
105 let new_indent = if is_last {
106 format!("{}{}", indent, s.indent_last)
107 } else {
108 format!("{}{}", indent, s.indent_mid)
109 };
110 result.push_str(&plot(&node.children, &new_indent, s, use_color));
111 }
112 }
113
114 result
115}
116
117pub fn plotfiles_txt(nodes: &[FileNode], indent: &str, style: Option<&TreeStyle>) -> String {
119 let default_style = TreeStyle::default();
120 let s = style.unwrap_or(&default_style);
121
122 plot(nodes, indent, s, false)
123}
124
125pub fn plotfiles_cli(nodes: &[FileNode], indent: &str, style: Option<&TreeStyle>) -> String {
127 let default_style = TreeStyle::default();
128 let s = style.unwrap_or(&default_style);
129
130 plot(nodes, indent, s, true)
131}