use std::cmp::Ordering;
use std::collections::HashMap;
use std::io::Write;
use std::path::Path;
use std::str;
pub fn sort_path_length(input: &str, invert: bool, output: &mut dyn Write) {
let mut path_hash_map: HashMap<usize, Vec<&str>> = HashMap::new();
for line_path in input.lines() {
let components = Path::new(line_path).components().collect::<Vec<_>>();
path_hash_map
.entry(components.len())
.and_modify(|v| {
if invert {
for (index, &l) in v.iter().enumerate() {
if line_path.partial_cmp(l).unwrap() == Ordering::Greater {
v.insert(index, line_path);
break;
}
}
} else {
for (index, &l) in v.iter().enumerate() {
if line_path.partial_cmp(l).unwrap() == Ordering::Less {
v.insert(index, line_path);
return;
}
}
v.push(line_path);
}
})
.or_insert(vec![line_path]);
}
let mut lengths = path_hash_map.keys().collect::<Vec<_>>();
if invert {
lengths.sort_by(|a, b| b.partial_cmp(a).unwrap());
} else {
lengths.sort();
}
for k in lengths {
if let Some(paths) = path_hash_map.get(k) {
for &p in paths {
output.write(p.as_bytes()).unwrap();
output.write("\n".as_bytes()).unwrap();
}
};
}
}
#[test]
pub fn test_default_sort_order() {
let input = "/a/absolute/path\n/a/b/c/d/e\n/a\n/a/dpasodj";
let mut output: Vec<u8> = Vec::new();
sort_path_length(input, false, &mut output);
let expected = "/a\n/a/dpasodj\n/a/absolute/path\n/a/b/c/d/e\n";
assert_eq!(expected, str::from_utf8(&output).unwrap());
}
#[test]
pub fn test_inverted_sort_order() {
let input = "/a/absolute/path\n/a/b/c/d/e\n/a\n/a/dpasodj";
let mut output: Vec<u8> = Vec::new();
sort_path_length(input, true, &mut output);
let expected = "/a/b/c/d/e\n/a/absolute/path\n/a/dpasodj\n/a\n";
assert_eq!(expected, str::from_utf8(&output).unwrap());
}
#[test]
pub fn test_default_sort_order_same_length_paths() {
let input = "/a/b/c/d/e
/b/c/d/e/f
/c/d/e/f/g
/a/e/d/c/b
/b/f/e/c/d
";
let mut output: Vec<u8> = Vec::new();
sort_path_length(input, false, &mut output);
let expected = "/a/b/c/d/e
/a/e/d/c/b
/b/c/d/e/f
/b/f/e/c/d
/c/d/e/f/g
";
assert_eq!(expected, str::from_utf8(&output).unwrap());
}
#[test]
pub fn test_inverted_sort_order_same_length_paths() {
let input = "/a/b/c/d/e
/b/c/d/e/f
/c/d/e/f/g
/a/e/d/c/b
/b/f/e/c/d
";
let mut output: Vec<u8> = Vec::new();
sort_path_length(input, true, &mut output);
let expected = "/c/d/e/f/g
/b/f/e/c/d
/b/c/d/e/f
/a/e/d/c/b
/a/b/c/d/e
";
assert_eq!(expected, str::from_utf8(&output).unwrap());
}