vaporise/src/main.rs

99 lines
2.6 KiB
Rust
Raw Normal View History

2024-03-26 13:55:15 +00:00
use anyhow::{Context, Result};
2024-03-13 19:27:25 +00:00
use clap::Parser;
use colored::Colorize;
2024-03-22 21:13:30 +00:00
use std::{fs, path, process};
use std::{io, io::Write};
2024-03-13 19:27:25 +00:00
#[derive(Parser, Debug)]
2024-03-13 20:23:48 +00:00
#[command(version, about, long_about = None, author)]
/// A simple, featureful and blazingly fast memory-safe alternative to 'rm' written in Rust.
2024-03-13 19:27:25 +00:00
struct Args {
/// Don't try to preserve '~' or '/'
#[arg(long)]
no_preserve: bool,
/// Ask once before removing all
#[arg(short, long)]
ask_once: bool,
/// Ask before removing each target
#[arg(short = 'x', long, conflicts_with = "ask_once")]
ask_each: bool,
2024-03-13 19:27:25 +00:00
#[arg(trailing_var_arg = true, allow_hyphen_values = false)]
targets: Vec<String>,
}
fn confirm_parse() {
io::stdout().flush().unwrap();
let mut confirm = String::new();
io::stdin().read_line(&mut confirm).expect("failed to read input");
if confirm != "y\n" {
process::exit(0);
}
}
fn confirm_once() {
print!("Are you sure you want to delete the specified targets? [y/N]: ");
confirm_parse();
}
fn confirm_each(target: &String) {
print!("Are you sure you want to delete {}? [y/N]: ", target);
confirm_parse();
}
fn vaporise() -> Result<()> {
2024-03-13 19:27:25 +00:00
let args = Args::parse();
2024-03-21 22:06:20 +00:00
if args.targets.is_empty() {
println!("{}: no arguments passed", "error".red().bold());
2024-03-22 21:13:30 +00:00
println!(
"{}: try 'vpr -h' for more information",
"note".cyan().bold()
2024-03-22 21:13:30 +00:00
);
2024-03-13 19:27:25 +00:00
process::exit(0);
}
if args.ask_once {
confirm_once();
}
2024-03-13 19:27:25 +00:00
for target in args.targets.iter() {
2024-03-21 22:06:20 +00:00
if !args.no_preserve && (target == "/" || target == "~") {
println!("{}: you're trying to delete an important directory ({})! specify '{}' if you really want to do this", "error".red().bold(), "--no-preserve".yellow(), target);
2024-03-21 22:06:20 +00:00
process::exit(0);
}
2024-03-22 21:13:30 +00:00
if args.ask_each {
confirm_each(target);
}
2024-03-13 19:27:25 +00:00
if path::Path::new(target).exists() {
if fs::metadata(target).unwrap().is_dir() {
fs::remove_dir_all(target)
.with_context(|| format!("could not remove directory: {}", target.bold()))?;
2024-03-13 19:27:25 +00:00
} else {
fs::remove_file(target)
.with_context(|| format!("could not remove file: {}", target.bold()))?;
2024-03-13 19:27:25 +00:00
}
} else {
2024-03-22 21:13:30 +00:00
println!(
"{}: the specified target does not exist {}",
"error".red().bold(),
2024-03-22 21:13:30 +00:00
target.yellow()
);
2024-03-13 19:27:25 +00:00
}
}
Ok(())
}
fn main() {
if let Err(error) = vaporise() {
println!("{}: {:?}", "error".red().bold(), error);
}
}