use clap::{ArgGroup, Parser}; #[derive(Parser)] #[command(author, version, about, long_about = None)] #[command(group( ArgGroup::new("vers") .required(true) .args(["set_ver", "major", "minor", "patch"]), ))] struct Cli { /// set version manually #[arg(long, value_name = "VER")] set_ver: Option, /// auto inc major #[arg(long)] major: bool, /// auto inc minor #[arg(long)] minor: bool, /// auto inc patch #[arg(long)] patch: bool, /// some regular input #[arg(group = "input")] input_file: Option, /// some special input argument #[arg(long, group = "input")] spec_in: Option, #[arg(short, requires = "input")] config: Option, } fn main() { let cli = Cli::parse(); // Let's assume the old version 1.2.3 let mut major = 1; let mut minor = 2; let mut patch = 3; // See if --set_ver was used to set the version manually let version = if let Some(ver) = cli.set_ver.as_deref() { ver.to_string() } else { // Increment the one requested (in a real program, we'd reset the lower numbers) let (maj, min, pat) = (cli.major, cli.minor, cli.patch); match (maj, min, pat) { (true, _, _) => major += 1, (_, true, _) => minor += 1, (_, _, true) => patch += 1, _ => unreachable!(), }; format!("{}.{}.{}", major, minor, patch) }; println!("Version: {}", version); // Check for usage of -c if let Some(config) = cli.config.as_deref() { let input = cli .input_file .as_deref() .unwrap_or_else(|| cli.spec_in.as_deref().unwrap()); println!("Doing work using input {} and config {}", input, config); } }