1#![deny(warnings)]
4#![deny(unsafe_code)]
5#![deny(missing_docs)]
6
7use clap::Parser;
8use rustutils_runnable::Runnable;
9use std::error::Error;
10use std::process::ExitCode;
11mod macros;
12
13macros::declare_utility! {
17 "arch" => rustutils_arch::Arch as Arch,
18 "cat" => rustutils_cat::Cat as Cat,
19 "false" => rustutils_false::False as False,
20 "pwd" => rustutils_pwd::Pwd as Pwd,
21 "rmdir" => rustutils_rmdir::Rmdir as Rmdir,
22 "seq" => rustutils_seq::Seq as Seq,
23 "sleep" => rustutils_sleep::Sleep as Sleep,
24 "tee" => rustutils_tee::Tee as Tee,
25 "true" => rustutils_true::True as True,
26 "uname" => rustutils_uname::Uname as Uname,
27 "unlink" => rustutils_unlink::Unlink as Unlink,
28 "wc" => rustutils_wc::Wc as Wc,
29 "yes" => rustutils_yes::Yes as Yes,
30 "dirname" => rustutils_dirname::Dirname as Dirname,
31 "basename" => rustutils_basename::Basename as Basename,
32 "mkdir" => rustutils_mkdir::Mkdir as Mkdir,
33 "env" => rustutils_env::Env as Env,
34 "printenv" => rustutils_printenv::Printenv as Printenv,
35 "base64" => rustutils_base64::Base64 as Base64,
36 "factor" => rustutils_factor::Factor as Factor
37}
38
39#[derive(Parser, Clone, Debug)]
42#[clap(author, version, about, long_about = None)]
43pub struct Coreutils {
44 #[clap(subcommand)]
45 util: Coreutil,
46}
47
48impl Runnable for Coreutils {
49 fn run(&self) -> Result<(), Box<dyn Error>> {
50 self.util.runnable().run()
51 }
52
53 fn main(&self) -> ExitCode {
54 self.util.runnable().main()
55 }
56}
57
58pub fn multicall_parse() -> Result<Option<Coreutil>, Box<dyn Error>> {
61 let executable = std::env::current_exe()?;
62 let file = executable.file_stem().and_then(|s| s.to_str());
63 let result = file.and_then(|name| Coreutil::parse(name));
64 Ok(result)
65}
66
67pub fn main() -> ExitCode {
72 if cfg!(feature = "multicall") {
73 match multicall_parse() {
74 Ok(Some(utility)) => utility.runnable().main(),
75 Ok(None) => Coreutils::parse().main(),
76 Err(error) => {
77 eprintln!("Error parsing multicall: {error}");
78 ExitCode::FAILURE
79 }
80 }
81 } else {
82 Coreutils::parse().main()
83 }
84}