feat: display the size of a file or directory in "kilobytes"

feat: display the size of a file or directory in "kilobytes"
This commit is contained in:
zhaotao1
2023-04-10 09:57:40 +08:00
committed by andy.boot
parent a4b5d8573b
commit e9bacdf875
11 changed files with 96 additions and 30 deletions

View File

@@ -193,6 +193,13 @@ pub fn build_cli() -> Command {
.action(clap::ArgAction::SetTrue)
.help("Only files will be displayed. (Finds your largest files)"),
)
.arg(
Arg::new("display_kb")
.short('k')
.long("display-kb")
.action(clap::ArgAction::SetTrue)
.help("display the size of a file or directory in kilobytes"),
)
.arg(
Arg::new("stack_size")
.short('S')

View File

@@ -26,6 +26,7 @@ pub struct Config {
pub disable_progress: Option<bool>,
pub depth: Option<usize>,
pub bars_on_right: Option<bool>,
pub display_kb: Option<bool>,
pub stack_size: Option<usize>,
}
@@ -104,6 +105,9 @@ impl Config {
from_cmd_line.copied()
}
}
pub fn get_display_kb(&self, options: &ArgMatches) -> bool {
Some(true) == self.display_kb || options.get_flag("display_kb")
}
}
fn convert_min_size(input: &str, iso: bool) -> Option<usize> {

View File

@@ -25,6 +25,7 @@ pub struct InitialDisplayData {
pub is_screen_reader: bool,
pub iso: bool,
pub bars_on_right: bool,
pub display_kb: bool,
}
pub struct DisplayData {
@@ -129,6 +130,7 @@ pub fn draw_it(
terminal_width: usize,
root_node: &DisplayNode,
skip_total: bool,
display_kb: bool,
) {
let biggest = match skip_total {
false => root_node,
@@ -142,7 +144,7 @@ pub fn draw_it(
let max_size = biggest.size;
max_size.separate_with_commas().chars().count()
} else {
find_biggest_size_str(root_node, idd.iso)
find_biggest_size_str(root_node, idd.iso, display_kb)
};
assert!(
@@ -190,10 +192,12 @@ pub fn draw_it(
}
}
fn find_biggest_size_str(node: &DisplayNode, iso: bool) -> usize {
let mut mx = human_readable_number(node.size, iso).chars().count();
fn find_biggest_size_str(node: &DisplayNode, iso: bool, display_kb: bool) -> usize {
let mut mx = human_readable_number(node.size, iso, display_kb)
.chars()
.count();
for n in node.children.iter() {
mx = max(mx, find_biggest_size_str(n, iso));
mx = max(mx, find_biggest_size_str(n, iso, display_kb));
}
mx
}
@@ -375,7 +379,11 @@ fn get_pretty_size(node: &DisplayNode, is_biggest: bool, display_data: &DisplayD
let output = if display_data.initial.by_filecount {
node.size.separate_with_commas()
} else {
human_readable_number(node.size, display_data.initial.iso)
human_readable_number(
node.size,
display_data.initial.iso,
display_data.initial.display_kb,
)
};
let spaces_to_add = display_data.num_chars_needed_on_left_most - output.chars().count();
let output = " ".repeat(spaces_to_add) + output.as_str();
@@ -407,9 +415,12 @@ fn get_pretty_name(
}
}
pub fn human_readable_number(size: u64, iso: bool) -> String {
pub fn human_readable_number(size: u64, iso: bool, display_kb: bool) -> String {
let num: u64 = if iso { 1000 } else { 1024 };
if display_kb {
return format!("{:.1}{}", (size as f32 / num as f32), 'K');
}
for (i, u) in UNITS.iter().enumerate() {
let num: u64 = if iso { 1000 } else { 1024 };
let marker = num.pow((UNITS.len() - i) as u32);
if size >= marker {
if size / marker < 10 {
@@ -438,6 +449,7 @@ mod tests {
is_screen_reader: false,
iso: false,
bars_on_right: false,
display_kb: false,
};
DisplayData {
initial,
@@ -503,20 +515,23 @@ mod tests {
#[test]
fn test_human_readable_number() {
assert_eq!(human_readable_number(1, false), "1B");
assert_eq!(human_readable_number(956, false), "956B");
assert_eq!(human_readable_number(1004, false), "1004B");
assert_eq!(human_readable_number(1024, false), "1.0K");
assert_eq!(human_readable_number(1536, false), "1.5K");
assert_eq!(human_readable_number(1024 * 512, false), "512K");
assert_eq!(human_readable_number(1024 * 1024, false), "1.0M");
assert_eq!(human_readable_number(1, false, false), "1B");
assert_eq!(human_readable_number(956, false, false), "956B");
assert_eq!(human_readable_number(1004, false, false), "1004B");
assert_eq!(human_readable_number(1024, false, false), "1.0K");
assert_eq!(human_readable_number(1536, false, false), "1.5K");
assert_eq!(human_readable_number(1024 * 512, false, false), "512K");
assert_eq!(human_readable_number(1024 * 1024, false, false), "1.0M");
assert_eq!(
human_readable_number(1024 * 1024 * 1024 - 1, false),
human_readable_number(1024 * 1024 * 1024 - 1, false, false),
"1023M"
);
assert_eq!(human_readable_number(1024 * 1024 * 1024 * 20, false), "20G");
assert_eq!(
human_readable_number(1024 * 1024 * 1024 * 1024, false),
human_readable_number(1024 * 1024 * 1024 * 20, false, false),
"20G"
);
assert_eq!(
human_readable_number(1024 * 1024 * 1024 * 1024, false, false),
"1.0T"
);
}
@@ -574,4 +589,16 @@ mod tests {
let bar = dd.generate_bar(&n, 5);
assert_eq!(bar, "████▓▓▓▓▓▓▓▓▓");
}
#[test]
fn test_human_readable_number_kb() {
assert_eq!(human_readable_number(1, false, true), "0.0K");
assert_eq!(human_readable_number(1024, false, true), "1.0K");
assert_eq!(human_readable_number(1536, false, true), "1.5K");
assert_eq!(human_readable_number(1024 * 512, false, true), "512.0K");
assert_eq!(human_readable_number(1024 * 1024, false, true), "1024.0K");
assert_eq!(
human_readable_number(1024 * 1000 * 1000 * 20, false, true),
"20000000.0K"
);
}
}

View File

@@ -180,11 +180,13 @@ fn main() {
let iso = config.get_iso(&options);
let display_kb = config.get_display_kb(&options);
let ignore_hidden = config.get_ignore_hidden(&options);
let mut indicator = PIndicator::build_me();
if !config.get_disable_progress(&options) {
indicator.spawn(iso);
indicator.spawn(iso, display_kb);
}
let walk_data = WalkData {
@@ -255,6 +257,7 @@ fn main() {
iso,
is_screen_reader: config.get_screen_reader(&options),
bars_on_right: config.get_bars_on_right(&options),
display_kb,
};
draw_it(
idd,
@@ -262,6 +265,7 @@ fn main() {
terminal_width,
&root_node,
config.get_skip_total(&options),
display_kb,
)
}
}

View File

@@ -77,16 +77,26 @@ pub struct RuntimeErrors {
/* -------------------------------------------------------------------------- */
fn format_preparing_str(prog_char: char, data: &PAtomicInfo, is_iso: bool) -> String {
fn format_preparing_str(
prog_char: char,
data: &PAtomicInfo,
is_iso: bool,
is_display_kb: bool,
) -> String {
let path_in = data.current_path.get();
let size = human_readable_number(data.total_file_size.load(ORDERING), is_iso);
let size = human_readable_number(data.total_file_size.load(ORDERING), is_iso, is_display_kb);
format!("Preparing: {path_in} {size} ... {prog_char}")
}
fn format_indexing_str(prog_char: char, data: &PAtomicInfo, is_iso: bool) -> String {
fn format_indexing_str(
prog_char: char,
data: &PAtomicInfo,
is_iso: bool,
display_kb: bool,
) -> String {
let path_in = data.current_path.get();
let file_count = data.num_files.load(ORDERING);
let size = human_readable_number(data.total_file_size.load(ORDERING), is_iso);
let size = human_readable_number(data.total_file_size.load(ORDERING), is_iso, display_kb);
let file_str = format!("{file_count} files, {size}");
format!("Indexing: {path_in} {file_str} ... {prog_char}")
}
@@ -106,7 +116,7 @@ impl PIndicator {
}
}
pub fn spawn(&mut self, is_iso: bool) {
pub fn spawn(&mut self, is_iso: bool, display_kb: bool) {
let data = self.data.clone();
let (stop_handler, receiver) = mpsc::channel::<()>();
@@ -125,8 +135,12 @@ impl PIndicator {
let prog_char = PROGRESS_CHARS[progress_char_i];
msg = match data.state.load(ORDERING) {
Operation::INDEXING => format_indexing_str(prog_char, &data, is_iso),
Operation::PREPARING => format_preparing_str(prog_char, &data, is_iso),
Operation::INDEXING => {
format_indexing_str(prog_char, &data, is_iso, display_kb)
}
Operation::PREPARING => {
format_preparing_str(prog_char, &data, is_iso, display_kb)
}
_ => panic!("Unknown State"),
};