use super::Cmd; use crate::args; use clap::{Arg, ArgAction, Command, ValueHint}; use std::{error::Error, fs, path::Path}; #[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), args::verbose(), ]) } fn run(&self, matches: &clap::ArgMatches) -> Result<(), Box> { if let Some(directories) = matches.get_many::("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 { Some(crate::Path::Bin) } } fn rmdir_recursive(dir: &Path, verbose: bool) -> Result<(), Box> { 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(()) }