mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
Merge pull request #31 from bootandy/nodes_rev
Refactor & support reverse
This commit is contained in:
Generated
+11
-11
@@ -22,7 +22,7 @@ dependencies = [
|
|||||||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ dependencies = [
|
|||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -141,7 +141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "du-dust"
|
name = "du-dust"
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -230,7 +230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -249,7 +249,7 @@ name = "quote"
|
|||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -382,14 +382,14 @@ name = "serde_derive"
|
|||||||
version = "1.0.101"
|
version = "1.0.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.40"
|
version = "1.0.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -407,7 +407,7 @@ dependencies = [
|
|||||||
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -422,7 +422,7 @@ name = "syn"
|
|||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -560,7 +560,7 @@ dependencies = [
|
|||||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||||
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
|
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
|
||||||
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
|
"checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0"
|
||||||
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
|
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
|
||||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||||
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||||
@@ -581,7 +581,7 @@ dependencies = [
|
|||||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
||||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
||||||
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
|
"checksum skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fb8ed853fdc19ce09752d63f3a2e5b5158aeb261520cd75eb618bd60305165"
|
||||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "du-dust"
|
name = "du-dust"
|
||||||
description = "A more intuitive version of du"
|
description = "A more intuitive version of du"
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
|
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
|
||||||
|
|
||||||
documentation = "https://github.com/bootandy/dust"
|
documentation = "https://github.com/bootandy/dust"
|
||||||
|
|||||||
+107
-135
@@ -2,137 +2,44 @@ extern crate ansi_term;
|
|||||||
|
|
||||||
use self::ansi_term::Colour::Fixed;
|
use self::ansi_term::Colour::Fixed;
|
||||||
use self::ansi_term::Style;
|
use self::ansi_term::Style;
|
||||||
use std::collections::HashSet;
|
use utils::Node;
|
||||||
use utils::{ensure_end_slash, strip_end_slash};
|
|
||||||
|
|
||||||
static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
|
static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
|
||||||
|
|
||||||
pub fn draw_it(
|
pub struct DisplayData {
|
||||||
permissions: bool,
|
pub short_paths: bool,
|
||||||
short_paths: bool,
|
pub is_reversed: bool,
|
||||||
depth: Option<u64>,
|
|
||||||
base_dirs: HashSet<String>,
|
|
||||||
to_display: Vec<(String, u64)>,
|
|
||||||
) {
|
|
||||||
if !permissions {
|
|
||||||
eprintln!("Did not have permissions for all directories");
|
|
||||||
}
|
|
||||||
let mut found = HashSet::new();
|
|
||||||
|
|
||||||
for &(ref k, _) in to_display.iter() {
|
|
||||||
if base_dirs.contains(k) {
|
|
||||||
display_node(&k, &mut found, &to_display, true, short_paths, depth, "─┬");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(nodes: &[(String, u64)], node_to_print: &str) -> Option<u64> {
|
impl DisplayData {
|
||||||
for &(ref k, ref v) in nodes.iter() {
|
fn get_first_chars(&self) -> &str {
|
||||||
if *k == *node_to_print {
|
if self.is_reversed {
|
||||||
return Some(*v);
|
"─┴"
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn display_node<S: Into<String>>(
|
|
||||||
node_to_print: &str,
|
|
||||||
found: &mut HashSet<String>,
|
|
||||||
to_display: &[(String, u64)],
|
|
||||||
is_biggest: bool,
|
|
||||||
short_paths: bool,
|
|
||||||
depth: Option<u64>,
|
|
||||||
indentation_str: S,
|
|
||||||
) {
|
|
||||||
if found.contains(node_to_print) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
found.insert(node_to_print.to_string());
|
|
||||||
|
|
||||||
let new_depth = match depth {
|
|
||||||
None => None,
|
|
||||||
Some(0) => return,
|
|
||||||
Some(d) => Some(d - 1),
|
|
||||||
};
|
|
||||||
match get_size(to_display, node_to_print) {
|
|
||||||
None => println!("Can not find path: {}", node_to_print),
|
|
||||||
Some(size) => {
|
|
||||||
let is = indentation_str.into();
|
|
||||||
print_this_node(node_to_print, size, is_biggest, short_paths, is.as_ref());
|
|
||||||
let new_indent = clean_indentation_string(is);
|
|
||||||
|
|
||||||
let ntp_with_slash = strip_end_slash(node_to_print);
|
|
||||||
|
|
||||||
// Annoying edge case for when run on root directory
|
|
||||||
let num_slashes = if ntp_with_slash == "/" {
|
|
||||||
1
|
|
||||||
} else {
|
} else {
|
||||||
ntp_with_slash.matches('/').count() + 1
|
"─┬"
|
||||||
};
|
}
|
||||||
let mut num_siblings = count_siblings(to_display, num_slashes - 1, node_to_print);
|
}
|
||||||
|
|
||||||
let mut is_biggest = true;
|
fn get_tree_chars(
|
||||||
for &(ref k, _) in to_display.iter() {
|
&self,
|
||||||
let temp = String::from(ensure_end_slash(node_to_print));
|
num_siblings: u64,
|
||||||
if k.starts_with(temp.as_str()) && k.matches('/').count() == num_slashes {
|
max_siblings: u64,
|
||||||
num_siblings -= 1;
|
has_children: bool,
|
||||||
let has_children = has_children(to_display, new_depth, k, num_slashes);
|
) -> &'static str {
|
||||||
display_node(
|
if self.is_reversed {
|
||||||
k,
|
if num_siblings == max_siblings - 1 {
|
||||||
found,
|
if has_children {
|
||||||
to_display,
|
"┌─┴"
|
||||||
is_biggest,
|
|
||||||
short_paths,
|
|
||||||
new_depth,
|
|
||||||
new_indent.to_string() + get_tree_chars(num_siblings != 0, has_children),
|
|
||||||
);
|
|
||||||
is_biggest = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clean_indentation_string<S: Into<String>>(s: S) -> String {
|
|
||||||
let mut is = s.into();
|
|
||||||
is = is.replace("└─┬", " ");
|
|
||||||
is = is.replace("└──", " ");
|
|
||||||
is = is.replace("├──", "│ ");
|
|
||||||
is = is.replace("├─┬", "│ ");
|
|
||||||
is = is.replace("─┬", " ");
|
|
||||||
is
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count_siblings(to_display: &[(String, u64)], num_slashes: usize, ntp: &str) -> u64 {
|
|
||||||
to_display.iter().fold(0, |a, b| {
|
|
||||||
if b.0.starts_with(ntp) && b.0.as_str().matches('/').count() == num_slashes + 1 {
|
|
||||||
a + 1
|
|
||||||
} else {
|
} else {
|
||||||
a
|
"┌──"
|
||||||
}
|
}
|
||||||
})
|
} else if has_children {
|
||||||
}
|
"├─┴"
|
||||||
|
} else {
|
||||||
fn has_children(
|
"├──"
|
||||||
to_display: &[(String, u64)],
|
|
||||||
new_depth: Option<u64>,
|
|
||||||
ntp: &str,
|
|
||||||
num_slashes: usize,
|
|
||||||
) -> bool {
|
|
||||||
if new_depth.is_none() || new_depth.unwrap() != 1 {
|
|
||||||
for &(ref k2, _) in to_display.iter() {
|
|
||||||
let ntp_with_slash = String::from(ntp.to_owned() + "/");
|
|
||||||
if k2.starts_with(ntp_with_slash.as_str()) && k2.matches('/').count() == num_slashes + 1
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if num_siblings == 0 {
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_tree_chars(has_smaller_siblings: bool, has_children: bool) -> &'static str {
|
|
||||||
if !has_smaller_siblings {
|
|
||||||
if has_children {
|
if has_children {
|
||||||
"└─┬"
|
"└─┬"
|
||||||
} else {
|
} else {
|
||||||
@@ -143,25 +50,90 @@ fn get_tree_chars(has_smaller_siblings: bool, has_children: bool) -> &'static st
|
|||||||
} else {
|
} else {
|
||||||
"├──"
|
"├──"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_biggest(&self, num_siblings: u64, max_siblings: u64) -> bool {
|
||||||
|
if self.is_reversed {
|
||||||
|
num_siblings == 0
|
||||||
|
} else {
|
||||||
|
num_siblings == max_siblings - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_children_from_node(&self, node: Node) -> impl Iterator<Item = Box<Node>> {
|
||||||
|
if self.is_reversed {
|
||||||
|
let n: Vec<Box<Node>> = node.children.into_iter().rev().map(|a| a).collect();
|
||||||
|
return n.into_iter();
|
||||||
|
} else {
|
||||||
|
return node.children.into_iter();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_this_node(
|
pub fn draw_it(permissions: bool, use_full_path: bool, is_reversed: bool, root_node: Node) {
|
||||||
node_name: &str,
|
if !permissions {
|
||||||
size: u64,
|
eprintln!("Did not have permissions for all directories");
|
||||||
is_biggest: bool,
|
}
|
||||||
short_paths: bool,
|
let display_data = DisplayData {
|
||||||
indentation: &str,
|
short_paths: !use_full_path,
|
||||||
) {
|
is_reversed,
|
||||||
|
};
|
||||||
|
|
||||||
|
for c in display_data.get_children_from_node(root_node) {
|
||||||
|
let first_tree_chars = display_data.get_first_chars();
|
||||||
|
display_node(*c, true, first_tree_chars, &display_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &DisplayData) {
|
||||||
|
let short = display_data.short_paths;
|
||||||
|
|
||||||
|
let mut num_siblings = node.children.len() as u64;
|
||||||
|
let max_sibling = num_siblings;
|
||||||
|
let new_indent = clean_indentation_string(indent);
|
||||||
|
let name = node.name.clone();
|
||||||
|
let size = node.size;
|
||||||
|
|
||||||
|
if !display_data.is_reversed {
|
||||||
|
print_this_node(&*name, size, is_biggest, short, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for c in display_data.get_children_from_node(node) {
|
||||||
|
num_siblings -= 1;
|
||||||
|
let chars = display_data.get_tree_chars(num_siblings, max_sibling, c.children.len() > 0);
|
||||||
|
let is_biggest = display_data.is_biggest(num_siblings, max_sibling);
|
||||||
|
let full_indent = new_indent.clone() + chars;
|
||||||
|
display_node(*c, is_biggest, &*full_indent, display_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if display_data.is_reversed {
|
||||||
|
print_this_node(&*name, size, is_biggest, short, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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("─┬", " ");
|
||||||
|
// For both
|
||||||
|
is = is.replace("├──", "│ ");
|
||||||
|
is
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_this_node(name: &str, size: u64, is_biggest: bool, short_paths: bool, indentation: &str) {
|
||||||
let pretty_size = format!("{:>5}", human_readable_number(size),);
|
let pretty_size = format!("{:>5}", human_readable_number(size),);
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
format_string(
|
format_string(name, is_biggest, short_paths, &*pretty_size, indentation)
|
||||||
node_name,
|
|
||||||
is_biggest,
|
|
||||||
short_paths,
|
|
||||||
pretty_size.as_ref(),
|
|
||||||
indentation
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+47
-5
@@ -5,7 +5,7 @@ extern crate walkdir;
|
|||||||
|
|
||||||
use self::display::draw_it;
|
use self::display::draw_it;
|
||||||
use clap::{App, AppSettings, Arg};
|
use clap::{App, AppSettings, Arg};
|
||||||
use utils::{find_big_ones, get_dir_tree, simplify_dir_names, sort, trim_deep_ones};
|
use utils::{find_big_ones, get_dir_tree, simplify_dir_names, sort, trim_deep_ones, Node};
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
mod utils;
|
mod utils;
|
||||||
@@ -43,6 +43,12 @@ fn main() {
|
|||||||
.long("apparent-size")
|
.long("apparent-size")
|
||||||
.help("If set will use file length. Otherwise we use blocks"),
|
.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))
|
.arg(Arg::with_name("inputs").multiple(true))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
@@ -91,14 +97,50 @@ fn main() {
|
|||||||
Some(d) => trim_deep_ones(sorted_data, d, &simplified_dirs),
|
Some(d) => trim_deep_ones(sorted_data, d, &simplified_dirs),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let tree = build_tree(biggest_ones, depth);
|
||||||
|
//println!("{:?}", tree);
|
||||||
|
|
||||||
draw_it(
|
draw_it(
|
||||||
permissions,
|
permissions,
|
||||||
!use_full_path,
|
use_full_path,
|
||||||
depth,
|
options.is_present("reverse"),
|
||||||
simplified_dirs,
|
tree,
|
||||||
biggest_ones,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_tree(biggest_ones: Vec<(String, u64)>, depth: Option<u64>) -> Node {
|
||||||
|
let mut top_parent = Node {
|
||||||
|
name: "".to_string(),
|
||||||
|
size: 0,
|
||||||
|
children: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
// assume sorted order
|
||||||
|
for b in biggest_ones {
|
||||||
|
let n = Node {
|
||||||
|
name: b.0,
|
||||||
|
size: b.1,
|
||||||
|
children: vec![],
|
||||||
|
};
|
||||||
|
recursively_build_tree(&mut top_parent, n, depth)
|
||||||
|
}
|
||||||
|
top_parent
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recursively_build_tree(parent_node: &mut Node, new_node: Node, depth: Option<u64>) {
|
||||||
|
let new_depth = match depth {
|
||||||
|
None => None,
|
||||||
|
Some(0) => return,
|
||||||
|
Some(d) => Some(d - 1),
|
||||||
|
};
|
||||||
|
for c in parent_node.children.iter_mut() {
|
||||||
|
if new_node.name.starts_with(&c.name) {
|
||||||
|
return recursively_build_tree(&mut *c, new_node, new_depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let temp = Box::<Node>::new(new_node);
|
||||||
|
parent_node.children.push(temp);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -109,6 +109,27 @@ pub fn test_apparent_size() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_reverse_flag() {
|
||||||
|
// variable names the same length make the output easier to read
|
||||||
|
let a = " ┌── a_file";
|
||||||
|
let b = " ├── hello_file";
|
||||||
|
let c = " ┌─┴ many";
|
||||||
|
let d = " ─┴ test_dir";
|
||||||
|
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["-r", "src/test_dir"])
|
||||||
|
.stdout()
|
||||||
|
.contains(a)
|
||||||
|
.stdout()
|
||||||
|
.contains(b)
|
||||||
|
.stdout()
|
||||||
|
.contains(c)
|
||||||
|
.stdout()
|
||||||
|
.contains(d)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_d_flag_works() {
|
pub fn test_d_flag_works() {
|
||||||
// We should see the top level directory but not the sub dirs / files:
|
// We should see the top level directory but not the sub dirs / files:
|
||||||
|
|||||||
+11
-2
@@ -7,6 +7,13 @@ use walkdir::WalkDir;
|
|||||||
mod platform;
|
mod platform;
|
||||||
use self::platform::*;
|
use self::platform::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Node {
|
||||||
|
pub name: String,
|
||||||
|
pub size: u64,
|
||||||
|
pub children: Vec<Box<Node>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
|
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
|
||||||
let mut top_level_names: HashSet<String> = HashSet::new();
|
let mut top_level_names: HashSet<String> = HashSet::new();
|
||||||
|
|
||||||
@@ -85,6 +92,7 @@ fn examine_dir(
|
|||||||
inodes.insert(inode_dev_pair);
|
inodes.insert(inode_dev_pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// This path and all its parent paths have their counter incremented
|
||||||
let mut e_path = e.path().to_path_buf();
|
let mut e_path = e.path().to_path_buf();
|
||||||
loop {
|
loop {
|
||||||
let path_name = e_path.to_string_lossy().to_string();
|
let path_name = e_path.to_string_lossy().to_string();
|
||||||
@@ -104,7 +112,8 @@ fn examine_dir(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn compare_tuple(a: &(String, u64), b: &(String, u64)) -> Ordering {
|
|
||||||
|
pub fn sort_by_size_first_name_second(a: &(String, u64), b: &(String, u64)) -> Ordering {
|
||||||
let result = b.1.cmp(&a.1);
|
let result = b.1.cmp(&a.1);
|
||||||
if result == Ordering::Equal {
|
if result == Ordering::Equal {
|
||||||
a.0.cmp(&b.0)
|
a.0.cmp(&b.0)
|
||||||
@@ -115,7 +124,7 @@ pub fn compare_tuple(a: &(String, u64), b: &(String, u64)) -> Ordering {
|
|||||||
|
|
||||||
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
|
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();
|
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));
|
new_l.sort_by(|a, b| sort_by_size_first_name_second(&a, &b));
|
||||||
new_l
|
new_l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user