1
+ use stfu8:: encode_u8;
2
+
3
+ use crate :: display:: get_printable_name;
1
4
use crate :: display_node:: DisplayNode ;
2
5
use crate :: node:: FileTime ;
3
6
use crate :: node:: Node ;
@@ -14,6 +17,7 @@ pub struct AggregateData {
14
17
pub number_of_lines : usize ,
15
18
pub depth : usize ,
16
19
pub using_a_filter : bool ,
20
+ pub short_paths : bool ,
17
21
}
18
22
19
23
pub fn get_biggest (
@@ -40,13 +44,17 @@ pub fn get_biggest(
40
44
} else {
41
45
top_level_nodes. iter ( ) . map ( |node| node. size ) . sum ( )
42
46
} ;
47
+
48
+ let nodes = handle_duplicate_top_level_names ( top_level_nodes, display_data. short_paths ) ;
49
+
43
50
root = Node {
44
51
name : PathBuf :: from ( "(total)" ) ,
45
52
size,
46
- children : top_level_nodes ,
53
+ children : nodes ,
47
54
inode_device : None ,
48
55
depth : 0 ,
49
56
} ;
57
+
50
58
// Always include the base nodes if we add a 'parent' (total) node
51
59
heap = always_add_children ( & display_data, & root, heap) ;
52
60
} else {
@@ -74,6 +82,8 @@ pub fn fill_remaining_lines<'a>(
74
82
let line = heap. pop ( ) ;
75
83
match line {
76
84
Some ( line) => {
85
+ // If we are not doing only_file OR if we are doing
86
+ // only_file and it has no children (ie is a file not a dir)
77
87
if !display_data. only_file || line. children . is_empty ( ) {
78
88
allowed_nodes. insert ( line. name . as_path ( ) , line) ;
79
89
}
@@ -161,3 +171,57 @@ fn build_display_node(mut new_children: Vec<DisplayNode>, current: &Node) -> Dis
161
171
children : new_children,
162
172
}
163
173
}
174
+
175
+ fn names_have_dup ( top_level_nodes : & Vec < Node > ) -> bool {
176
+ let mut stored = HashSet :: new ( ) ;
177
+ for node in top_level_nodes {
178
+ let name = get_printable_name ( & node. name , true ) ;
179
+ if stored. contains ( & name) {
180
+ return true ;
181
+ }
182
+ stored. insert ( name) ;
183
+ }
184
+ false
185
+ }
186
+
187
+ fn handle_duplicate_top_level_names ( top_level_nodes : Vec < Node > , short_paths : bool ) -> Vec < Node > {
188
+ // If we have top level names that are the same - we need to tweak them:
189
+ if short_paths && names_have_dup ( & top_level_nodes) {
190
+ let mut new_top_nodes = top_level_nodes. clone ( ) ;
191
+ let mut dir_walk_up_count = 0 ;
192
+
193
+ while names_have_dup ( & new_top_nodes) && dir_walk_up_count < 10 {
194
+ dir_walk_up_count += 1 ;
195
+ let mut newer = vec ! [ ] ;
196
+
197
+ for node in new_top_nodes. iter ( ) {
198
+ let mut folders = node. name . iter ( ) . rev ( ) ;
199
+ // Get parent folder (if second time round get grandparent and so on)
200
+ for _ in 0 ..dir_walk_up_count {
201
+ folders. next ( ) ;
202
+ }
203
+ match folders. next ( ) {
204
+ // Add (parent_name) to path of Node
205
+ Some ( data) => {
206
+ let parent = encode_u8 ( data. as_encoded_bytes ( ) ) ;
207
+ let current_node = node. name . display ( ) ;
208
+ let n = Node {
209
+ name : PathBuf :: from ( format ! ( "{current_node}({parent})" ) ) ,
210
+ size : node. size ,
211
+ children : node. children . clone ( ) ,
212
+ inode_device : node. inode_device ,
213
+ depth : node. depth ,
214
+ } ;
215
+ newer. push ( n)
216
+ }
217
+ // Node does not have a parent
218
+ None => newer. push ( node. clone ( ) ) ,
219
+ }
220
+ }
221
+ new_top_nodes = newer;
222
+ }
223
+ new_top_nodes
224
+ } else {
225
+ top_level_nodes
226
+ }
227
+ }
0 commit comments