use std::{
fs,
path::{Path, PathBuf},
};
use bytesize::ByteSize;
use crate::config;
fn get_file_size_in_bytes(path: &PathBuf) -> Result<u64, String> {
if path.is_file() {
fs::metadata(path)
.map_err(|e| e.to_string())
.and_then(|metadata| Ok(metadata.len()))
} else {
Err("The given path is not a file.".to_string())
}
}
fn calculate_size(path: &PathBuf) -> u64 {
if path.is_file() {
if let Ok(file_size) = get_file_size_in_bytes(&path) {
return file_size;
}
}
let script_template: &'static str = include_str!("./get-folder-size.template");
let script = script_template.replace('%', &path.to_string_lossy());
let result = rosascript::run_apple_script(&script.as_str());
result.parse::<u64>().unwrap_or(0)
}
fn pad_end(s: &str, target_length: usize, pad_char: char) -> String {
if s.len() >= target_length {
return s.to_string();
}
let padding = pad_char.to_string().repeat(target_length - s.len());
format!("{}{}", s, padding)
}
fn pad_start(s: &str, target_length: usize, pad_char: char) -> String {
if s.len() >= target_length {
return s.to_string();
}
let padding = pad_char.to_string().repeat(target_length - s.len());
format!("{}{}", padding, s)
}
fn format_size(size: u64) -> String {
if (config::OPTS.bytes) {
return size.to_string();
}
let size_formatted = ByteSize::b(size).to_string();
let rtn = size_formatted.replace('B', "").replace(' ', "");
return rtn;
}
fn format_path(abs_path: &PathBuf, index: usize) -> String {
let path_arg = &config::OPTS.paths[0];
if (config::OPTS.list) {
let file_name = abs_path.file_name().unwrap();
let joined = path_arg.join(file_name);
return joined.to_string_lossy().into_owned();
}
return path_arg.to_string_lossy().into_owned();
}
pub fn process_paths(paths: Vec<PathBuf>) {
for (index, path) in paths.iter().enumerate() {
let path_formatted = format_path(path, index);
let size = calculate_size(&path);
let size_formatted = format_size(size);
println!(
"{} {}",
pad_end(&size_formatted, 8, ' '),
path_formatted,
);
}
}