shitbox/src/cmd/rmdir/mod.rs

72 lines
2.3 KiB
Rust
Raw Normal View History

2023-01-16 23:44:21 -05:00
use std::{io, error::Error, fs, path::Path};
use super::Cmd;
use clap::{Arg, ArgAction, Command, ValueHint};
2022-12-20 12:05:21 -05:00
2023-01-16 23:44:21 -05:00
#[derive(Debug, Default)]
pub struct Rmdir;
impl Cmd for Rmdir {
fn cli(&self) -> clap::Command {
Command::new("rmdir")
.about("remove directories")
.author("Nathan Fisher")
.version(env!("CARGO_PKG_VERSION"))
.args([
Arg::new("parents")
.help("remove DIRECTORY and it's ancestors")
.short('p')
.long("parents")
.action(ArgAction::SetTrue),
Arg::new("dir")
.num_args(1..)
.value_name("DIRECTORY")
.value_hint(ValueHint::DirPath)
.required(true),
Arg::new("verbose")
.help("output a diagnostic for every directory processed")
.short('v')
.long("verbose")
.action(ArgAction::SetTrue),
])
}
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
let Some(matches) = matches else {
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input")));
};
if let Some(directories) = matches.get_many::<String>("dir") {
for dir in directories {
if matches.get_flag("parents") {
let path = Path::new(dir);
rmdir_recursive(path, matches.get_flag("verbose"))?;
} else {
fs::remove_dir(dir)?;
if matches.get_flag("verbose") {
println!("rmdir: removing directory, '{dir}'");
}
}
}
}
Ok(())
}
fn path(&self) -> Option<crate::Path> {
Some(crate::Path::Bin)
}
}
fn rmdir_recursive(dir: &Path, verbose: bool) -> Result<(), Box<dyn Error>> {
fs::remove_dir(dir)?;
if verbose {
println!("rmdir: removing directory, '{}'", dir.display());
}
if let Some(parent) = dir.parent() {
if let Some(name) = parent.to_str() {
if !name.is_empty() {
rmdir_recursive(parent, verbose)?;
}
}
}
Ok(())
}