fud/src/main.rs

72 lines
1.9 KiB
Rust

use clap::Parser;
mod walk;
mod directory;
use walk::walk;
use std::fs::File;
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",
default_value_t = false,
)]
minimal: bool,
#[arg(
short, long,
help = "only display the total size",
default_value_t = false,
)]
total_only: bool,
#[arg(value_parser = validate_path, default_value_t = String::from("."), help = "directory to begin search from")]
path: String,
}
fn validate_path(s: &str) -> Result<String, String> {
let here = File::open(s).map_err(|e| e.to_string())?;
let meta = here.metadata().map_err(|e| e.to_string())?;
if meta.is_dir() {
return Ok(s.to_owned())
} else if meta.is_file() {
return Err("this is a file (hint: use wc to view file sizes)".to_owned());
} else {
return Err("this is not a directory".to_owned());
}
}
fn main() -> ExitCode {
let args = Args::parse();
let dir_structure = match walk(args.clone()) {
Ok(dir) => dir,
Err(e) => return e,
};
if args.minimal {
print!("{}", dir_structure.size);
} else {
let size = dir_structure.size; // copy size before print consumes dir_structure
dir_structure.print();
// looks like "print the total unless asked to", but "total: " is to prevent
// the root from getting lost in massive outputs
if !args.total_only {
println!("total: {size}");
}
}
ExitCode::SUCCESS
}