1use std::cmp::Ordering;
2use std::collections::HashMap;
3use std::io::Write;
4use std::path::Path;
5use std::str;
6
7pub fn sort_path_length(input: &str, invert: bool, output: &mut dyn Write) {
13 let mut path_hash_map: HashMap<usize, Vec<&str>> = HashMap::new();
14
15 for line_path in input.lines() {
16 let components = Path::new(line_path).components().collect::<Vec<_>>();
17 path_hash_map
18 .entry(components.len())
19 .and_modify(|v| {
20 if invert {
22 for (index, &l) in v.iter().enumerate() {
23 if line_path.partial_cmp(l).unwrap() == Ordering::Greater {
24 v.insert(index, line_path);
25 break;
26 }
27 }
28 } else {
29 for (index, &l) in v.iter().enumerate() {
30 if line_path.partial_cmp(l).unwrap() == Ordering::Less {
31 v.insert(index, line_path);
32 return;
36 }
37 }
38
39 v.push(line_path);
40 }
41 })
42 .or_insert(vec![line_path]);
43 }
44
45 let mut lengths = path_hash_map.keys().collect::<Vec<_>>();
46
47 if invert {
48 lengths.sort_by(|a, b| b.partial_cmp(a).unwrap());
49 } else {
50 lengths.sort();
51 }
52
53 for k in lengths {
55 if let Some(paths) = path_hash_map.get(k) {
56 for &p in paths {
57 output.write(p.as_bytes()).unwrap();
58 output.write("\n".as_bytes()).unwrap();
59 }
60 };
61 }
62}
63
64#[test]
65pub fn test_default_sort_order() {
66 let input = "/a/absolute/path\n/a/b/c/d/e\n/a\n/a/dpasodj";
67
68 let mut output: Vec<u8> = Vec::new();
69
70 sort_path_length(input, false, &mut output);
71
72 let expected = "/a\n/a/dpasodj\n/a/absolute/path\n/a/b/c/d/e\n";
73
74 assert_eq!(expected, str::from_utf8(&output).unwrap());
75}
76
77#[test]
78pub fn test_inverted_sort_order() {
79 let input = "/a/absolute/path\n/a/b/c/d/e\n/a\n/a/dpasodj";
80
81 let mut output: Vec<u8> = Vec::new();
82
83 sort_path_length(input, true, &mut output);
84
85 let expected = "/a/b/c/d/e\n/a/absolute/path\n/a/dpasodj\n/a\n";
86
87 assert_eq!(expected, str::from_utf8(&output).unwrap());
88}
89
90#[test]
91pub fn test_default_sort_order_same_length_paths() {
92 let input = "/a/b/c/d/e
93/b/c/d/e/f
94/c/d/e/f/g
95/a/e/d/c/b
96/b/f/e/c/d
97";
98
99 let mut output: Vec<u8> = Vec::new();
100
101 sort_path_length(input, false, &mut output);
102
103 let expected = "/a/b/c/d/e
104/a/e/d/c/b
105/b/c/d/e/f
106/b/f/e/c/d
107/c/d/e/f/g
108";
109
110 assert_eq!(expected, str::from_utf8(&output).unwrap());
111}
112
113#[test]
114pub fn test_inverted_sort_order_same_length_paths() {
115 let input = "/a/b/c/d/e
116/b/c/d/e/f
117/c/d/e/f/g
118/a/e/d/c/b
119/b/f/e/c/d
120";
121
122 let mut output: Vec<u8> = Vec::new();
123 sort_path_length(input, true, &mut output);
124
125 let expected = "/c/d/e/f/g
126/b/f/e/c/d
127/b/c/d/e/f
128/a/e/d/c/b
129/a/b/c/d/e
130";
131
132 assert_eq!(expected, str::from_utf8(&output).unwrap());
133}