104 lines
2.5 KiB
Rust
104 lines
2.5 KiB
Rust
#![feature(io_error_more, fs_try_exists)]
|
|
|
|
use clap::Parser;
|
|
use clap::ArgAction;
|
|
|
|
mod directory;
|
|
use directory::Directory;
|
|
|
|
use std::process::ExitCode;
|
|
|
|
#[derive(Parser, Debug, Clone)]
|
|
pub struct Args {
|
|
#[arg(
|
|
short, long, default_value_t = false,
|
|
help = "keep going if an error occurs",
|
|
long_help = "keep going if an error occurs (ex. unreadable subdirectories in a readable directory)"
|
|
)]
|
|
persistant: bool,
|
|
|
|
#[arg(
|
|
short, long,
|
|
help = "minimize output",
|
|
long_help = "like -t, but does not print \"total: \" before the summary or the newline after. It also surpresses all error messages",
|
|
conflicts_with = "total_only",
|
|
default_value_t = false,
|
|
)]
|
|
minimal: bool,
|
|
|
|
#[arg(
|
|
short, long,
|
|
help = "only display the total size",
|
|
conflicts_with = "minimal",
|
|
default_value_t = false,
|
|
)]
|
|
total_only: bool,
|
|
|
|
#[arg(
|
|
short='2', long,
|
|
help = "print sizes in powers of 1024",
|
|
default_value_t = false,
|
|
conflicts_with = "si"
|
|
)]
|
|
base_two: bool,
|
|
|
|
#[arg(
|
|
short='0', long,
|
|
help = "print sizes in powers of 1000",
|
|
default_value_t = false,
|
|
conflicts_with = "base_two"
|
|
)]
|
|
si: bool,
|
|
|
|
#[arg(
|
|
value_parser = validate_path,
|
|
help = "directories to summate",
|
|
action = ArgAction::Append,
|
|
num_args = 1..
|
|
)]
|
|
path: Vec<String>,
|
|
}
|
|
|
|
fn validate_path(s: &str) -> Result<String, String> {
|
|
// try to access it's metadata, since that is what is used
|
|
// to get its length
|
|
std::fs::metadata(s)
|
|
.map(|_| s.to_string())
|
|
.map_err(|e| e.to_string())
|
|
}
|
|
|
|
fn main() -> ExitCode {
|
|
let args = Args::parse();
|
|
|
|
let mut total = 0;
|
|
for path in args.path {
|
|
let dir_structure = match Directory::new(path) {
|
|
Ok(ds) => ds,
|
|
Err(e) => {
|
|
if !args.minimal {
|
|
eprintln!("hb: {e}");
|
|
}
|
|
return ExitCode::FAILURE;
|
|
}
|
|
};
|
|
|
|
total += dir_structure.size();
|
|
|
|
if !args.minimal {
|
|
if args.total_only {
|
|
println!("{}: {}", dir_structure.path().to_str().unwrap(), dir_structure.size());
|
|
} else {
|
|
print!("{}", dir_structure.display());
|
|
}
|
|
}
|
|
}
|
|
|
|
if args.total_only {
|
|
println!("total: {total}");
|
|
}
|
|
else if args.minimal {
|
|
print!("{total}");
|
|
}
|
|
|
|
ExitCode::SUCCESS
|
|
} |