From a8c8ba58191a1a6eb6dd0caf79f19baf4d7c5d51 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Fri, 13 Jan 2023 01:08:32 -0500 Subject: [PATCH] Simplified Cmd trait, trimmed 600K from binary size --- src/cmd/base32/mod.rs | 22 +++--------------- src/cmd/base64/mod.rs | 24 ++++---------------- src/cmd/basename/mod.rs | 24 ++++---------------- src/cmd/bootstrap/mod.rs | 31 +++++++------------------- src/cmd/clear/mod.rs | 4 ---- src/cmd/dirname/mod.rs | 22 +++--------------- src/cmd/echo/mod.rs | 27 +++++----------------- src/cmd/factor/mod.rs | 24 ++++---------------- src/cmd/false/mod.rs | 27 +++++----------------- src/cmd/fold/mod.rs | 26 +++++----------------- src/cmd/groups/mod.rs | 4 ---- src/cmd/head/mod.rs | 24 ++++---------------- src/cmd/hostname/mod.rs | 23 +++++-------------- src/cmd/link/mod.rs | 30 +++++++++---------------- src/cmd/mod.rs | 2 +- src/cmd/mountpoint/mod.rs | 47 ++++++++++++--------------------------- src/cmd/nologin/mod.rs | 24 ++++---------------- src/cmd/nproc/mod.rs | 24 ++++---------------- src/cmd/rev/mod.rs | 26 +++++----------------- src/cmd/shitbox/mod.rs | 29 ++++-------------------- src/cmd/sleep/mod.rs | 27 +++++----------------- src/cmd/true/mod.rs | 27 +++++----------------- src/cmd/which/mod.rs | 15 +++++-------- src/cmd/whoami/mod.rs | 7 +----- src/cmd/yes/mod.rs | 24 ++++---------------- src/lib.rs | 7 +++--- src/pw/mod.rs | 24 ++++++++------------ 27 files changed, 124 insertions(+), 471 deletions(-) diff --git a/src/cmd/base32/mod.rs b/src/cmd/base32/mod.rs index 3839d01..63cc400 100644 --- a/src/cmd/base32/mod.rs +++ b/src/cmd/base32/mod.rs @@ -8,26 +8,10 @@ use std::{ }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -#[derive(Debug)] -pub struct Base32 { - name: &'static str, - path: Option, -} - -impl Default for Base32 { - fn default() -> Self { - Self { - name: "base32", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Base32; impl Cmd for Base32 { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { Command::new("base32") .author("Nathan Fisher") @@ -121,7 +105,7 @@ impl Cmd for Base32 { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/base64/mod.rs b/src/cmd/base64/mod.rs index 6e3d11d..924f6a8 100644 --- a/src/cmd/base64/mod.rs +++ b/src/cmd/base64/mod.rs @@ -8,26 +8,10 @@ use std::{ }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -#[derive(Debug)] -pub struct Base64 { - name: &'static str, - path: Option, -} - -impl Default for Base64 { - fn default() -> Self { - Self { - name: "base64", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Base64; impl Cmd for Base64 { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> Command { Command::new("base64") .author("Nathan Fisher") @@ -119,7 +103,7 @@ impl Cmd for Base64 { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } @@ -129,7 +113,7 @@ fn decode_base64(mut contents: String, ignore: bool) -> Result<(), Box, -} - -impl Default for Basename { - fn default() -> Self { - Self { - name: "basename", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Basename; impl Cmd for Basename { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("basename") .about("Print NAME with any leading directory components removed.") .long_about( "Print NAME with any leading directory components removed.\n\ @@ -62,6 +46,6 @@ impl Cmd for Basename { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/bootstrap/mod.rs b/src/cmd/bootstrap/mod.rs index 2d765d1..61ffea2 100644 --- a/src/cmd/bootstrap/mod.rs +++ b/src/cmd/bootstrap/mod.rs @@ -11,20 +11,8 @@ use std::{ path::{Path, PathBuf}, }; -#[derive(Debug)] -pub struct Bootstrap { - name: &'static str, - path: Option, -} - -impl Default for Bootstrap { - fn default() -> Self { - Self { - name: "bootstrap", - path: None, - } - } -} +#[derive(Debug, Default)] +pub struct Bootstrap; impl Bootstrap { fn all() -> clap::Command { @@ -127,12 +115,8 @@ impl Bootstrap { } impl Cmd for Bootstrap { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("bootstrap") .version(env!("CARGO_PKG_VERSION")) .author("Nathan Fisher") .about("Install shitbox into the filesystem") @@ -212,7 +196,7 @@ impl Cmd for Bootstrap { } fn path(&self) -> Option { - self.path + None } } @@ -225,7 +209,8 @@ pub trait BootstrapCmd { impl BootstrapCmd for dyn Cmd { fn completion(&self, outdir: &Path, gen: &str) -> Result<(), io::Error> { - let name = self.name(); + let cmd = self.cli(); + let name = cmd.get_name(); let mut cmd = self.cli(); if !outdir.exists() { fs::create_dir_all(outdir)?; @@ -249,7 +234,7 @@ impl BootstrapCmd for dyn Cmd { Some(p) => path.push(p.to_str(usr)), None => return None, } - path.push(self.name()); + path.push(self.cli().get_name()); Some(path) } @@ -289,7 +274,7 @@ impl BootstrapCmd for dyn Cmd { fn manpage(&self, prefix: &str) -> Result<(), io::Error> { let command = self.cli(); - let fname = match self.name() { + let fname = match command.get_name() { "bootstrap" => "shitbox-bootstrap.1".to_string(), s => format!("{s}.1"), }; diff --git a/src/cmd/clear/mod.rs b/src/cmd/clear/mod.rs index b552f39..5ae0c02 100644 --- a/src/cmd/clear/mod.rs +++ b/src/cmd/clear/mod.rs @@ -5,10 +5,6 @@ use clap::Command; pub struct Clear; impl Cmd for Clear { - fn name(&self) -> &str { - "clear" - } - fn cli(&self) -> Command { Command::new("clear") .about("clear the terminal's screen") diff --git a/src/cmd/dirname/mod.rs b/src/cmd/dirname/mod.rs index 957b14c..257868c 100644 --- a/src/cmd/dirname/mod.rs +++ b/src/cmd/dirname/mod.rs @@ -2,26 +2,10 @@ use super::Cmd; use clap::{Arg, ArgAction, Command}; use std::path::Path; -#[derive(Debug)] -pub struct Dirname { - name: &'static str, - path: Option, -} - -impl Default for Dirname { - fn default() -> Self { - Self { - name: "dirname", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Dirname; 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") @@ -61,6 +45,6 @@ impl Cmd for Dirname { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/echo/mod.rs b/src/cmd/echo/mod.rs index fd801b7..15dbd29 100644 --- a/src/cmd/echo/mod.rs +++ b/src/cmd/echo/mod.rs @@ -1,30 +1,13 @@ use super::Cmd; -use crate::Path; use clap::{Arg, Command}; use std::{env, error::Error}; -#[derive(Debug)] -pub struct Echo { - name: &'static str, - path: Option, -} - -impl Default for Echo { - fn default() -> Self { - Self { - name: "echo", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct Echo; impl Cmd for Echo { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("echo") .about("Display a line of text") .long_about("Echo the STRING(s) to standard output") .author("Nathan Fisher") @@ -39,7 +22,7 @@ impl Cmd for Echo { fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box> { let args: Vec = env::args().collect(); let idx = match crate::progname() { - Some(s) if s.as_str() == self.name() => 1, + Some(s) if s.as_str() == "echo" => 1, Some(_) => 2, None => unreachable!(), }; @@ -60,6 +43,6 @@ impl Cmd for Echo { } fn path(&self) -> Option { - self.path + Some(crate::Path::Bin) } } diff --git a/src/cmd/factor/mod.rs b/src/cmd/factor/mod.rs index b363264..f18ef90 100644 --- a/src/cmd/factor/mod.rs +++ b/src/cmd/factor/mod.rs @@ -1,30 +1,14 @@ -use crate::Cmd; +use super::Cmd; use clap::{value_parser, Arg, ArgMatches, Command}; use std::{ error::Error, io::{self, BufRead}, }; -#[derive(Debug)] -pub struct Factor { - name: &'static str, - path: Option, -} - -impl Default for Factor { - fn default() -> Self { - Self { - name: "factor", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Factor; impl Cmd for Factor { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> Command { Command::new("factor") .about("factor numbers") @@ -59,7 +43,7 @@ impl Cmd for Factor { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/false/mod.rs b/src/cmd/false/mod.rs index f0eebdb..b6ea090 100644 --- a/src/cmd/false/mod.rs +++ b/src/cmd/false/mod.rs @@ -1,30 +1,13 @@ use super::Cmd; -use crate::Path; use clap::Command; use std::{error::Error, process}; -#[derive(Debug)] -pub struct False { - name: &'static str, - path: Option, -} - -impl Default for False { - fn default() -> Self { - Self { - name: "false", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct False; impl Cmd for False { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("false") .about("Does nothing unsuccessfully") .long_about("Exit with a status code indicating failure") .author("Nathan Fisher") @@ -34,7 +17,7 @@ impl Cmd for False { process::exit(1); } - fn path(&self) -> Option { - self.path + fn path(&self) -> Option { + Some(crate::Path::Bin) } } diff --git a/src/cmd/fold/mod.rs b/src/cmd/fold/mod.rs index 32f22aa..9ac0c66 100644 --- a/src/cmd/fold/mod.rs +++ b/src/cmd/fold/mod.rs @@ -6,28 +6,12 @@ use std::{ }; use textwrap::{fill, wrap_algorithms::WrapAlgorithm}; -#[derive(Debug)] -pub struct Fold { - name: &'static str, - path: Option, -} - -impl Default for Fold { - fn default() -> Self { - Self { - name: "fold", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Fold; impl Cmd for Fold { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> Command { - Command::new(self.name) + Command::new("fold") .about("Wrap each input line to fit in specified width") .author("Nathan Fisher") .after_long_help("With no FILE, or when FILE is -, read standard input") @@ -84,12 +68,12 @@ impl Cmd for Fold { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } fn wrap_line(line: &str, args: &ArgMatches) { - let width = args.get_one("WIDTH").map(|x| *x).unwrap_or(80); + let width = args.get_one("WIDTH").map_or(80, |x| *x); if args.get_flag("OPTIMAL") { let line = line.replace('\t', " "); let opts = textwrap::Options::new(width).wrap_algorithm(WrapAlgorithm::new_optimal_fit()); diff --git a/src/cmd/groups/mod.rs b/src/cmd/groups/mod.rs index a66c02b..fdb0edc 100644 --- a/src/cmd/groups/mod.rs +++ b/src/cmd/groups/mod.rs @@ -7,10 +7,6 @@ use std::io; pub struct Groups; impl Cmd for Groups { - fn name(&self) -> &str { - "groups" - } - fn cli(&self) -> clap::Command { Command::new("groups") .about("display current group names") diff --git a/src/cmd/head/mod.rs b/src/cmd/head/mod.rs index bff65fd..7ddceb8 100644 --- a/src/cmd/head/mod.rs +++ b/src/cmd/head/mod.rs @@ -9,28 +9,12 @@ use std::{ }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -#[derive(Debug)] -pub struct Head { - name: &'static str, - path: Option, -} - -impl Default for Head { - fn default() -> Self { - Self { - name: "head", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct Head; impl Cmd for Head { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> Command { - Command::new(self.name) + Command::new("head") .author("Nathan Fisher") .about("Display first lines of a file") .long_about( @@ -133,7 +117,7 @@ impl Cmd for Head { } fn path(&self) -> Option { - self.path + Some(crate::Path::Bin) } } diff --git a/src/cmd/hostname/mod.rs b/src/cmd/hostname/mod.rs index 82bfab3..93c400c 100644 --- a/src/cmd/hostname/mod.rs +++ b/src/cmd/hostname/mod.rs @@ -1,27 +1,14 @@ use super::Cmd; -use crate::Path; use clap::{Arg, ArgAction, ArgMatches, Command}; use std::{error::Error, io}; -#[derive(Debug)] -pub struct Hostname { - name: &'static str, - path: Option, -} - -pub const HOSTNAME: Hostname = Hostname { - name: "hostname", - path: Some(Path::Bin), -}; +#[derive(Debug, Default)] +pub struct Hostname; impl Cmd for Hostname { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) - .author("The JeanG3nie ") + Command::new("hostname") + .author("Nathan Fisher") .about("Prints the name of the current host. The super-user can set the host name by supplying an argument.") .args([ Arg::new("NAME") @@ -62,6 +49,6 @@ impl Cmd for Hostname { } fn path(&self) -> Option { - self.path + Some(crate::Path::Bin) } } diff --git a/src/cmd/link/mod.rs b/src/cmd/link/mod.rs index 4d43c99..69aaf45 100644 --- a/src/cmd/link/mod.rs +++ b/src/cmd/link/mod.rs @@ -6,10 +6,6 @@ use std::{fs, io}; pub struct Link; impl Cmd for Link { - fn name(&self) -> &str { - "link" - } - fn cli(&self) -> clap::Command { Command::new("link") .about("call the link function to create a link to a file") @@ -29,23 +25,17 @@ impl Cmd for Link { let Some(matches) = matches else { return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input"))); }; - let f1 = match matches.get_one::("file1") { - Some(s) => s, - None => { - return Err(Box::new(io::Error::new( - io::ErrorKind::Other, - "missing file 1", - ))) - } + let Some(f1) = matches.get_one::("file1") else { + return Err(Box::new(io::Error::new( + io::ErrorKind::Other, + "missing file 1", + ))) }; - let f2 = match matches.get_one::("file2") { - Some(s) => s, - None => { - return Err(Box::new(io::Error::new( - io::ErrorKind::Other, - "missing file 2", - ))) - } + let Some(f2) = matches.get_one::("file2") else { + return Err(Box::new(io::Error::new( + io::ErrorKind::Other, + "missing file 2", + ))) }; fs::hard_link(f1, f2)?; if matches.get_flag("verbose") { diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index f7eda74..36404c4 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -48,12 +48,12 @@ pub use { }; pub trait Cmd: fmt::Debug + Sync { - fn name(&self) -> &str; fn cli(&self) -> clap::Command; fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box>; fn path(&self) -> Option; } +#[must_use] pub fn get(name: &str) -> Option> { match name { "base64" => Some(Box::new(Base64::default())), diff --git a/src/cmd/mountpoint/mod.rs b/src/cmd/mountpoint/mod.rs index 3165892..0f15d58 100644 --- a/src/cmd/mountpoint/mod.rs +++ b/src/cmd/mountpoint/mod.rs @@ -9,28 +9,12 @@ use std::{ process, }; -#[derive(Debug)] -pub struct Mountpoint { - name: &'static str, - path: Option, -} - -impl Default for Mountpoint { - fn default() -> Self { - Self { - name: "mountpoint", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct Mountpoint; impl Cmd for Mountpoint { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("mountpoint") .about("see if a directory or file is a mountpoint") .author("Nathan Fisher") .after_long_help( @@ -77,12 +61,11 @@ impl Cmd for Mountpoint { }; let file = matches.get_one::("file").unwrap(); if matches.get_flag("fs-devno") { - match fs_devno(file)? { - Some(maj_min) => println!("{maj_min}"), - None => { - println!("{file} is not a mountpoint"); - process::exit(32); - } + if let Some(maj_min) = fs_devno(file)? { + println!("{maj_min}"); + } else { + println!("{file} is not a mountpoint"); + process::exit(32); } } else if matches.get_flag("devno") { let devno = devno(file)?; @@ -94,18 +77,16 @@ impl Cmd for Mountpoint { println!("{file} is a mountpoint"); } return Ok(()); - } else { - if !matches.get_flag("quiet") { - println!("{file} is not a mountpoint"); - } - process::exit(32); + } else if !matches.get_flag("quiet") { + println!("{file} is not a mountpoint"); } + process::exit(32); } Ok(()) } fn path(&self) -> Option { - self.path + Some(crate::Path::Bin) } } @@ -114,7 +95,7 @@ fn is_mountpoint(path: &str) -> Result> { let reader = BufReader::new(fd); for line in reader.lines() { let line = line?; - if let Some(mntpt) = line.split_whitespace().skip(1).next() { + if let Some(mntpt) = line.split_whitespace().nth(1) { if mntpt == path { return Ok(true); } @@ -135,7 +116,7 @@ fn fs_devno(path: &str) -> Result, Box> { let line = line?; let mut line = line.split_whitespace().skip(2); if let Some(maj_min) = line.next() { - if let Some(mntpt) = line.skip(1).next() { + if let Some(mntpt) = line.nth(1) { if mntpt == path { return Ok(Some(String::from(maj_min))); } diff --git a/src/cmd/nologin/mod.rs b/src/cmd/nologin/mod.rs index 1b918f3..43fc229 100644 --- a/src/cmd/nologin/mod.rs +++ b/src/cmd/nologin/mod.rs @@ -2,28 +2,12 @@ use super::Cmd; use clap::Command; use std::process; -#[derive(Debug)] -pub struct Nologin { - name: &'static str, - path: Option, -} - -impl Default for Nologin { - fn default() -> Self { - Self { - name: "nologin", - path: Some(crate::Path::Sbin), - } - } -} +#[derive(Debug, Default)] +pub struct Nologin; impl Cmd for Nologin { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("nologin") .author("Nathan Fisher") .about("Denies a user account login ability") } @@ -34,6 +18,6 @@ impl Cmd for Nologin { } fn path(&self) -> Option { - self.path + Some(crate::Path::Sbin) } } diff --git a/src/cmd/nproc/mod.rs b/src/cmd/nproc/mod.rs index 20e21be..52d3369 100644 --- a/src/cmd/nproc/mod.rs +++ b/src/cmd/nproc/mod.rs @@ -2,28 +2,12 @@ use super::Cmd; use clap::{Arg, ArgAction, Command}; use std::io; -#[derive(Debug)] -pub struct Nproc { - name: &'static str, - path: Option, -} - -impl Default for Nproc { - fn default() -> Self { - Self { - name: "nproc", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Nproc; impl Cmd for Nproc { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("nproc") .author("Nathan Fisher") .about("Print the number of processing units available") .arg( @@ -48,6 +32,6 @@ impl Cmd for Nproc { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/rev/mod.rs b/src/cmd/rev/mod.rs index e4cce80..24fb903 100644 --- a/src/cmd/rev/mod.rs +++ b/src/cmd/rev/mod.rs @@ -1,4 +1,4 @@ -use crate::Cmd; +use super::Cmd; use clap::{Arg, ArgAction, Command}; use std::{ fs::File, @@ -6,28 +6,12 @@ use std::{ }; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -#[derive(Debug)] -pub struct Rev { - name: &'static str, - path: Option, -} - -impl Default for Rev { - fn default() -> Self { - Self { - name: "rev", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Rev; impl Cmd for Rev { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("rev") .about("reverse lines characterwise") .author("Nathan Fisher") .args([ @@ -82,7 +66,7 @@ impl Cmd for Rev { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/cmd/shitbox/mod.rs b/src/cmd/shitbox/mod.rs index 32f7837..20063e5 100644 --- a/src/cmd/shitbox/mod.rs +++ b/src/cmd/shitbox/mod.rs @@ -6,31 +6,10 @@ use std::{ process, }; -#[derive(Debug)] -pub struct Shitbox { - name: &'static str, - path: Option, -} - -impl Default for Shitbox { - fn default() -> Self { - Self { - name: "shitbox", - path: None, - } - } -} - -pub const SHITBOX: Shitbox = Shitbox { - name: "shitbox", - path: None, -}; +#[derive(Debug, Default)] +pub struct Shitbox; impl Cmd for Shitbox { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { let subcommands: Vec = { let mut s = vec![]; @@ -44,7 +23,7 @@ impl Cmd for Shitbox { } s }; - Command::new(self.name) + Command::new("shitbox") .about("The box store multitool of embedded Linux") .version(env!("CARGO_PKG_VERSION")) .propagate_version(true) @@ -70,6 +49,6 @@ impl Cmd for Shitbox { } fn path(&self) -> Option { - self.path + None } } diff --git a/src/cmd/sleep/mod.rs b/src/cmd/sleep/mod.rs index 74b05e0..b7111fe 100644 --- a/src/cmd/sleep/mod.rs +++ b/src/cmd/sleep/mod.rs @@ -1,30 +1,13 @@ use super::Cmd; -use crate::Path; use clap::{value_parser, Arg, ArgAction, ArgMatches, Command}; use std::{env, error::Error, thread, time::Duration}; -#[derive(Debug)] -pub struct Sleep { - name: &'static str, - path: Option, -} - -impl Default for Sleep { - fn default() -> Self { - Self { - name: "sleep", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct Sleep; impl Cmd for Sleep { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("sleep") .about("Suspend execution for an interval of time") .long_about( "The sleep utility suspends execution for a minimum of the specified number of seconds.\n\ @@ -54,7 +37,7 @@ impl Cmd for Sleep { Ok(()) } - fn path(&self) -> Option { - self.path + fn path(&self) -> Option { + Some(crate::Path::Bin) } } diff --git a/src/cmd/true/mod.rs b/src/cmd/true/mod.rs index 1544016..3506d76 100644 --- a/src/cmd/true/mod.rs +++ b/src/cmd/true/mod.rs @@ -1,30 +1,13 @@ use super::Cmd; -use crate::Path; use clap::Command; use std::{error::Error, process}; -#[derive(Debug)] -pub struct True { - name: &'static str, - path: Option, -} - -impl Default for True { - fn default() -> Self { - Self { - name: "true", - path: Some(crate::Path::Bin), - } - } -} +#[derive(Debug, Default)] +pub struct True; impl Cmd for True { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("true") .about("Does nothing successfully") .long_about("Exit with a status code indicating success") .author("Nathan Fisher") @@ -34,7 +17,7 @@ impl Cmd for True { process::exit(0); } - fn path(&self) -> Option { - self.path + fn path(&self) -> Option { + Some(crate::Path::Bin) } } diff --git a/src/cmd/which/mod.rs b/src/cmd/which/mod.rs index 7a4d711..79df4d8 100644 --- a/src/cmd/which/mod.rs +++ b/src/cmd/which/mod.rs @@ -6,10 +6,6 @@ use std::{env, fs::File, io, os::unix::prelude::MetadataExt, path::PathBuf, proc pub struct Which; impl Cmd for Which { - fn name(&self) -> &str { - "which" - } - fn cli(&self) -> clap::Command { Command::new("which") .about("Write the full path of COMMAND(s) to standard output") @@ -31,12 +27,11 @@ impl Cmd for Which { let mut failures = 0; if let Some(commands) = matches.get_many::("COMMAND") { for command in commands { - match which(command, &path) { - Some(p) => println!("{p}"), - None => { - println!("{}: no {} in ({})", self.name(), command, &rawpath); - failures += 1; - } + if let Some(p) = which(command, &path) { + println!("{p}"); + } else { + println!("which: no {} in ({})", command, &rawpath); + failures += 1; } } } else { diff --git a/src/cmd/whoami/mod.rs b/src/cmd/whoami/mod.rs index 207ce6e..adea215 100644 --- a/src/cmd/whoami/mod.rs +++ b/src/cmd/whoami/mod.rs @@ -1,19 +1,14 @@ -use std::ffi::CStr; - use { super::Cmd, clap::Command, libc::{geteuid, getpwuid}, + std::ffi::CStr, }; #[derive(Debug, Default)] pub struct Whoami; impl Cmd for Whoami { - fn name(&self) -> &str { - "whoami" - } - fn cli(&self) -> clap::Command { Command::new("whoami") .about("print effective user name") diff --git a/src/cmd/yes/mod.rs b/src/cmd/yes/mod.rs index 76942f4..37ef44c 100644 --- a/src/cmd/yes/mod.rs +++ b/src/cmd/yes/mod.rs @@ -2,28 +2,12 @@ use super::Cmd; use clap::{Arg, Command}; use std::io; -#[derive(Debug)] -pub struct Yes { - name: &'static str, - path: Option, -} - -impl Default for Yes { - fn default() -> Self { - Self { - name: "yes", - path: Some(crate::Path::UsrBin), - } - } -} +#[derive(Debug, Default)] +pub struct Yes; impl Cmd for Yes { - fn name(&self) -> &str { - self.name - } - fn cli(&self) -> clap::Command { - Command::new(self.name) + Command::new("yes") .about("output a string repeatedly until killed") .author("Nathan Fisher") .arg(Arg::new("msg").num_args(1).default_value("y")) @@ -40,6 +24,6 @@ impl Cmd for Yes { } fn path(&self) -> Option { - self.path + Some(crate::Path::UsrBin) } } diff --git a/src/lib.rs b/src/lib.rs index 4afdae4..536487e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,14 +16,13 @@ pub enum Path { } impl Path { + #[must_use] pub fn to_str(&self, usr: bool) -> &'static str { match self { - Self::Bin => "bin", Self::UsrBin if usr => "usr/bin", - Self::UsrBin => "bin", - Self::Sbin => "sbin", Self::UsrSbin if usr => "usr/sbin", - Self::UsrSbin => "sbin", + Self::Bin | Self::UsrBin => "bin", + Self::Sbin | Self::UsrSbin => "sbin", } } } diff --git a/src/pw/mod.rs b/src/pw/mod.rs index c3e53f3..772045b 100644 --- a/src/pw/mod.rs +++ b/src/pw/mod.rs @@ -25,35 +25,28 @@ pub fn get_eusername<'a>() -> Result<&'a str, std::str::Utf8Error> { } pub fn get_uid_for_name(name: &str) -> Option { - let user = match CString::new(name.as_bytes()) { - Ok(n) => n, - Err(_) => return None, - }; - let uid = unsafe { + let Ok(user) = CString::new(name.as_bytes()) else { return None }; + unsafe { let pw = libc::getpwnam(user.as_ptr()); if pw.is_null() { None } else { Some((*pw).pw_uid) } - }; - uid + } } +#[must_use] pub fn get_pgid_for_name(name: &str) -> Option { - let user = match CString::new(name.as_bytes()) { - Ok(n) => n, - Err(_) => return None, - }; - let gid = unsafe { + let Ok(user) = CString::new(name.as_bytes()) else { return None }; + unsafe { let pw = libc::getpwnam(user.as_ptr()); if pw.is_null() { None } else { Some((*pw).pw_gid) } - }; - gid + } } pub fn get_grpname<'a>() -> Result<&'a str, std::str::Utf8Error> { @@ -89,6 +82,7 @@ pub fn get_gids() -> Result, num::TryFromIntError> { Ok(buf) } +#[allow(clippy::cast_sign_loss)] pub fn get_gids_for_name(name: &str) -> Result, Box> { let gid = match get_pgid_for_name(name) { Some(g) => g as libc::gid_t, @@ -111,7 +105,7 @@ pub fn get_gids_for_name(name: &str) -> Result, Box> { ))); } } - Ok(buf[0..ct as usize].iter().map(|x| *x as u32).collect()) + Ok(buf[0..ct as usize].to_vec()) } pub fn get_group_names() -> Result, Box> {