From 1e1e909afe966d75559bf11e27bfbccdeaf8a8fd Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Sun, 8 Jan 2023 01:12:36 -0500 Subject: [PATCH] Added `basename` applet --- src/cmd/basename/mod.rs | 67 +++++++++++++++++++++++++++++++++++++++++ src/cmd/mod.rs | 13 +++++--- src/cmd/nproc/mod.rs | 4 +-- 3 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 src/cmd/basename/mod.rs diff --git a/src/cmd/basename/mod.rs b/src/cmd/basename/mod.rs new file mode 100644 index 0000000..d82ff8d --- /dev/null +++ b/src/cmd/basename/mod.rs @@ -0,0 +1,67 @@ +use super::Cmd; +use clap::{Arg, ArgMatches, Command}; +use std::io; + +#[derive(Debug)] +pub struct Basename { + name: &'static str, + path: Option, +} + +impl Default for Basename { + fn default() -> Self { + Self { + name: "basename", + path: Some(crate::Path::UsrBin), + } + } +} + +impl Cmd for Basename { + fn name(&self) -> &str { + self.name + } + + fn cli(&self) -> clap::Command { + Command::new(self.name) + .about("Print NAME with any leading directory components removed.") + .long_about( + "Print NAME with any leading directory components removed.\n\ + If specified, also remove a trailing SUFFIX.", + ) + .author("Nathan Fisher") + .args([ + Arg::new("NAME") + .index(1) + .required(true) + .help("the filename to process"), + Arg::new("SUFFIX") + .index(2) + .required(false) + .help("the suffix to be removed"), + ]) + } + + fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box> { + let Some(matches) = matches else { + return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input"))); + }; + if let Some(mut base) = matches + .get_one::("NAME") + .and_then(|x| x.split('/').last()) + { + if let Some(suffix) = matches.get_one::("SUFFIX") { + base = match base.strip_suffix(suffix) { + Some(b) => b, + None => base, + }; + } + println!("{base}"); + } + Ok(()) + } + + fn path(&self) -> Option { + self.path + } +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index d708b9b..535c3cc 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -3,6 +3,7 @@ use std::{error::Error, fmt}; pub mod base32; pub mod base64; +pub mod basename; pub mod bootstrap; mod cat; mod chmod; @@ -33,10 +34,10 @@ pub mod r#true; pub mod yes; pub use { - self::hostname::Hostname, base32::Base32, base64::Base64, bootstrap::Bootstrap, - dirname::Dirname, echo::Echo, factor::Factor, head::Head, mountpoint::Mountpoint, - nologin::Nologin, nproc::Nproc, r#false::False, r#true::True, rev::Rev, shitbox::Shitbox, sleep::Sleep, - yes::Yes, + self::hostname::Hostname, base32::Base32, base64::Base64, basename::Basename, + bootstrap::Bootstrap, dirname::Dirname, echo::Echo, factor::Factor, head::Head, + mountpoint::Mountpoint, nologin::Nologin, nproc::Nproc, r#false::False, r#true::True, rev::Rev, + shitbox::Shitbox, sleep::Sleep, yes::Yes, }; pub trait Cmd: fmt::Debug + Sync { @@ -50,6 +51,7 @@ pub fn get(name: &str) -> Option> { match name { "base64" => Some(Box::new(Base64::default())), "base32" => Some(Box::new(Base32::default())), + "basename" => Some(Box::new(Basename::default())), "bootstrap" => Some(Box::new(Bootstrap::default())), "dirname" => Some(Box::new(Dirname::default())), "echo" => Some(Box::new(Echo::default())), @@ -68,9 +70,10 @@ pub fn get(name: &str) -> Option> { } } -pub static COMMANDS: [&'static str; 17] = [ +pub static COMMANDS: [&'static str; 18] = [ "base32", "base64", + "basename", "bootstrap", "dirname", "echo", diff --git a/src/cmd/nproc/mod.rs b/src/cmd/nproc/mod.rs index a640926..20e21be 100644 --- a/src/cmd/nproc/mod.rs +++ b/src/cmd/nproc/mod.rs @@ -1,6 +1,6 @@ -use clap::{Arg, Command, ArgAction}; -use std::io; use super::Cmd; +use clap::{Arg, ArgAction, Command}; +use std::io; #[derive(Debug)] pub struct Nproc {