A way of supporting reverse

This commit is contained in:
andy.boot
2019-10-02 22:31:49 +01:00
parent ec2d9e19d4
commit 1d9a56e025
3 changed files with 100 additions and 25 deletions
+75 -23
View File
@@ -13,15 +13,32 @@ pub fn draw_it(
depth: Option<u64>,
base_dirs: HashSet<String>,
to_display: Vec<(String, u64)>,
is_reversed: bool,
) {
if !permissions {
eprintln!("Did not have permissions for all directories");
}
let mut found = HashSet::new();
let first_tree_chars = {
if is_reversed {
"─┴"
} else {
"─┬"
}
};
for &(ref k, _) in to_display.iter() {
if base_dirs.contains(k) {
display_node(&k, &mut found, &to_display, true, short_paths, depth, "─┬");
display_node(
&k,
&mut found,
&to_display,
true,
short_paths,
depth,
first_tree_chars,
is_reversed,
);
}
}
}
@@ -36,18 +53,19 @@ fn get_size(nodes: &[(String, u64)], node_to_print: &str) -> Option<u64> {
}
fn display_node(
node_to_print: &str,
found: &mut HashSet<String>,
node: &str,
nodes_already_found: &mut HashSet<String>,
to_display: &[(String, u64)],
is_biggest: bool,
short_paths: bool,
depth: Option<u64>,
indentation_str: &str,
indent: &str,
is_reversed: bool,
) {
if found.contains(node_to_print) {
if nodes_already_found.contains(node) {
return;
}
found.insert(node_to_print.to_string());
nodes_already_found.insert(node.to_string());
let new_depth = match depth {
None => None,
@@ -55,35 +73,36 @@ fn display_node(
Some(d) => Some(d - 1),
};
match get_size(to_display, node_to_print) {
None => println!("Can not find path: {}", node_to_print),
match get_size(to_display, node) {
None => println!("Can not find path: {}", node),
Some(size) => {
print_this_node(
node_to_print,
size,
is_biggest,
short_paths,
indentation_str,
);
if !is_reversed {
print_this_node(node, size, is_biggest, short_paths, indent);
}
fan_out(
node_to_print,
found,
node,
nodes_already_found,
to_display,
short_paths,
new_depth,
indentation_str,
indent,
is_reversed,
);
if is_reversed {
print_this_node(node, size, is_biggest, short_paths, indent);
}
}
}
}
fn fan_out(
node_to_print: &str,
found: &mut HashSet<String>,
nodes_already_found: &mut HashSet<String>,
to_display: &[(String, u64)],
short_paths: bool,
new_depth: Option<u64>,
indentation_str: &str,
is_reversed: bool,
) {
let new_indent = clean_indentation_string(indentation_str);
let num_slashes = strip_end_slash_including_root(node_to_print)
@@ -98,14 +117,26 @@ fn fan_out(
if k.starts_with(temp.as_str()) && k.matches('/').count() == num_slashes + 1 {
num_siblings -= 1;
let has_children = has_children(to_display, new_depth, k, num_slashes + 1);
let (new_tree_chars, biggest) = if is_reversed {
(
get_tree_chars_reversed(num_siblings != max_siblings - 1, has_children),
num_siblings == 0,
)
} else {
(
get_tree_chars(num_siblings != 0, has_children),
num_siblings == max_siblings - 1,
)
};
display_node(
k,
found,
nodes_already_found,
to_display,
num_siblings == max_siblings - 1,
biggest,
short_paths,
new_depth,
&*(new_indent.to_string() + get_tree_chars(num_siblings != 0, has_children)),
&*(new_indent.to_string() + new_tree_chars),
is_reversed,
);
}
}
@@ -113,11 +144,18 @@ fn fan_out(
fn clean_indentation_string(s: &str) -> String {
let mut is: String = s.into();
// For reversed:
is = is.replace("┌─┴", " ");
is = is.replace("┌──", " ");
is = is.replace("├─┴", "");
is = is.replace("─┴", " ");
// For normal
is = is.replace("└─┬", " ");
is = is.replace("└──", " ");
is = is.replace("├──", "");
is = is.replace("├─┬", "");
is = is.replace("─┬", " ");
// For both
is = is.replace("├──", "");
is
}
@@ -163,6 +201,20 @@ fn get_tree_chars(has_smaller_siblings: bool, has_children: bool) -> &'static st
}
}
fn get_tree_chars_reversed(has_smaller_siblings: bool, has_children: bool) -> &'static str {
if !has_smaller_siblings {
if has_children {
"┌─┴"
} else {
"┬──"
}
} else if has_children {
"├─┴"
} else {
"├──"
}
}
fn print_this_node(
node_name: &str,
size: u64,
+16 -2
View File
@@ -5,7 +5,10 @@ extern crate walkdir;
use self::display::draw_it;
use clap::{App, AppSettings, Arg};
use utils::{find_big_ones, get_dir_tree, simplify_dir_names, sort, trim_deep_ones};
use utils::{
compare_tuple_smallest_first, find_big_ones, get_dir_tree, simplify_dir_names, sort,
trim_deep_ones,
};
mod display;
mod utils;
@@ -43,6 +46,12 @@ fn main() {
.long("apparent-size")
.help("If set will use file length. Otherwise we use blocks"),
)
.arg(
Arg::with_name("reverse")
.short("r")
.long("reverse")
.help("If applied tree will be printed upside down (biggest lowest)"),
)
.arg(Arg::with_name("inputs").multiple(true))
.get_matches();
@@ -85,18 +94,23 @@ fn main() {
let simplified_dirs = simplify_dir_names(target_dirs);
let (permissions, nodes) = get_dir_tree(&simplified_dirs, use_apparent_size);
let sorted_data = sort(nodes);
let biggest_ones = {
let mut biggest_ones = {
match depth {
None => find_big_ones(sorted_data, number_of_lines + simplified_dirs.len()),
Some(d) => trim_deep_ones(sorted_data, d, &simplified_dirs),
}
};
if options.is_present("reverse") {
biggest_ones.sort_by(compare_tuple_smallest_first);
}
draw_it(
permissions,
!use_full_path,
depth,
simplified_dirs,
biggest_ones,
options.is_present("reverse"),
);
}
+9
View File
@@ -121,6 +121,15 @@ pub fn compare_tuple(a: &(String, u64), b: &(String, u64)) -> Ordering {
}
}
pub fn compare_tuple_smallest_first(a: &(String, u64), b: &(String, u64)) -> Ordering {
let result = a.1.cmp(&b.1);
if result == Ordering::Equal {
b.0.cmp(&a.0)
} else {
result
}
}
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
new_l.sort_by(|a, b| compare_tuple(&a, &b));