shitbox/src/cmd/dirname/mod.rs
Nathan Fisher fb389fd309 Simplify subcommand parsing:
- one match statement to return a `Box<dyn Cmd>`
- one array containing all command names
Only two places to register new commands (besides their module), both in
crate::cmd::mod.rs. Also removes `once_cell` crate dependency.

Replace `base64` crate dependency with `data_encoding::BASE64` so that
both base32 and base64 commands use the same crate.
2023-01-06 23:41:02 -05:00

67 lines
1.8 KiB
Rust

use super::Cmd;
use clap::{Arg, ArgAction, Command};
use std::path::Path;
#[derive(Debug)]
pub struct Dirname {
name: &'static str,
path: Option<crate::Path>,
}
impl Default for Dirname {
fn default() -> Self {
Self {
name: "dirname",
path: Some(crate::Path::UsrBin),
}
}
}
impl Cmd for Dirname {
fn name(&self) -> &str {
self.name
}
fn cli(&self) -> clap::Command {
Command::new("dirname")
.about("strip last component from file name")
.args([
Arg::new("zero")
.short('z')
.long("zero")
.help("end each output line with NUL, not newline")
.action(ArgAction::SetTrue),
Arg::new("name").num_args(1..).required(true),
])
}
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
if let Some(matches) = matches {
if let Some(names) = matches.get_many::<String>("name") {
names.for_each(|name| {
let path = match Path::new(name).parent() {
Some(p) => p,
None => Path::new("."),
};
let path = path.to_string_lossy();
let path = if path.is_empty() {
String::from(".")
} else {
path.to_string()
};
if matches.get_flag("zero") {
print!("{path}\0");
} else {
println!("{path}");
}
});
}
}
Ok(())
}
fn path(&self) -> Option<crate::Path> {
self.path
}
}