This is a very slight abstraction on top of pico-args, to reduce boilerplate code a bit for CLI subcommand handling.
No functional changes. Signed-off-by: Christoph Heiss <c.he...@proxmox.com> --- Cargo.toml | 1 + debian/control | 1 + proxmox-installer-common/Cargo.toml | 4 ++ proxmox-installer-common/src/cli.rs | 62 +++++++++++++++++++++++++++++ proxmox-installer-common/src/lib.rs | 3 ++ 5 files changed, 71 insertions(+) create mode 100644 proxmox-installer-common/src/cli.rs diff --git a/Cargo.toml b/Cargo.toml index bfec8f7..4165b96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ edition = "2024" [workspace.dependencies] anyhow = "1.0" log = "0.4.20" +pico-args = "0.5" regex = "1.7" serde = "1.0" serde_json = "1.0" diff --git a/debian/control b/debian/control index dec07ed..51c45a4 100644 --- a/debian/control +++ b/debian/control @@ -15,6 +15,7 @@ Build-Depends: cargo:native, librust-glob-0.3-dev, librust-hex-0.4-dev, librust-native-tls-dev, + librust-pico-args-0.5-dev, librust-pretty-assertions-1.4-dev, librust-regex-1+default-dev (>= 1.7~~), librust-rustls-0.21+dangerous-configuration-dev, diff --git a/proxmox-installer-common/Cargo.toml b/proxmox-installer-common/Cargo.toml index 4bdb2b0..8a6fb5c 100644 --- a/proxmox-installer-common/Cargo.toml +++ b/proxmox-installer-common/Cargo.toml @@ -22,6 +22,9 @@ rustls-native-certs = { version = "0.6", optional = true } sha2 = { version = "0.10", optional = true } ureq = { version = "2.6", features = [ "native-certs", "native-tls" ], optional = true } +# `cli` feature +pico-args = { workspace = true, optional = true } + [features] http = [ "dep:hex", @@ -31,6 +34,7 @@ http = [ "dep:sha2", "dep:ureq" ] +cli = [ "dep:pico-args" ] [dev-dependencies] pretty_assertions = "1.4" diff --git a/proxmox-installer-common/src/cli.rs b/proxmox-installer-common/src/cli.rs new file mode 100644 index 0000000..1539001 --- /dev/null +++ b/proxmox-installer-common/src/cli.rs @@ -0,0 +1,62 @@ +//! Provides a simple command line parsing interface, with special support for +//! (one-level deep) subcommands. + +use std::process; + +use anyhow::Result; + +pub use pico_args::Arguments; + +pub trait Subcommand { + /// Parses the arguments for this command from an [`pico_args::Arguments`]. + fn parse(args: &mut Arguments) -> Result<Self> + where + Self: Sized; + + /// Print command usage to stderr. + fn print_usage() + where + Self: Sized; + + /// Runs the commands action. + fn run(&self) -> Result<()>; +} + +pub struct AppInfo<'a> { + pub global_help: &'a str, + pub on_command: fn(Option<&str>, &mut Arguments) -> Result<()>, +} + +pub fn run(info: AppInfo) -> process::ExitCode { + if let Err(err) = parse_args(&info) { + eprintln!("Error: {err:#}\n\n{}", info.global_help); + process::ExitCode::FAILURE + } else { + process::ExitCode::SUCCESS + } +} + +fn parse_args(info: &AppInfo) -> Result<()> { + let mut args = pico_args::Arguments::from_env(); + let subcommand = args.subcommand()?; + + if subcommand.is_none() && args.contains(["-h", "--help"]) { + eprintln!("{}", info.global_help); + Ok(()) + } else if args.contains(["-V", "--version"]) { + eprintln!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")); + Ok(()) + } else { + (info.on_command)(subcommand.as_deref(), &mut args) + } +} + +pub fn handle_command<T: Subcommand>(args: &mut pico_args::Arguments) -> Result<()> { + if args.contains(["-h", "--help"]) { + T::print_usage(); + } else if let Err(err) = T::parse(args).and_then(|cmd| cmd.run()) { + eprint!("Error: {err:#}"); + } + + Ok(()) +} diff --git a/proxmox-installer-common/src/lib.rs b/proxmox-installer-common/src/lib.rs index 3dc3bfb..ea907a0 100644 --- a/proxmox-installer-common/src/lib.rs +++ b/proxmox-installer-common/src/lib.rs @@ -7,6 +7,9 @@ pub mod utils; #[cfg(feature = "http")] pub mod http; +#[cfg(feature = "cli")] +pub mod cli; + pub const RUNTIME_DIR: &str = "/run/proxmox-installer"; /// Default placeholder value for the administrator email address. -- 2.49.0 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel