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,56 @@ 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) {
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
+ for _ in 0 ..dir_walk_up_count {
200
+ folders. next ( ) ;
201
+ }
202
+ match folders. next ( ) {
203
+ Some ( data) => {
204
+ let parent = encode_u8 ( data. as_encoded_bytes ( ) ) ;
205
+ let current_node = node. name . display ( ) ;
206
+ let n = Node {
207
+ name : PathBuf :: from ( format ! ( "{current_node}({parent})" ) ) ,
208
+ size : node. size ,
209
+ children : node. children . clone ( ) ,
210
+ inode_device : node. inode_device ,
211
+ depth : node. depth ,
212
+ } ;
213
+ newer. push ( n)
214
+ }
215
+ None => {
216
+ return top_level_nodes;
217
+ }
218
+ }
219
+ }
220
+ new_top_nodes = newer;
221
+ }
222
+ new_top_nodes
223
+ } else {
224
+ top_level_nodes
225
+ }
226
+ }
0 commit comments