| 1 | use std::path::PathBuf; |
| 2 | |
| 3 | use clap::{arg, command, value_parser, ArgAction, ArgGroup}; |
| 4 | |
| 5 | fn main() { |
| 6 | // Create application like normal |
| 7 | let matches = command!() // requires `cargo` feature |
| 8 | // Add the version arguments |
| 9 | .arg(arg!(--"set-ver" <VER> "set version manually" )) |
| 10 | .arg(arg!(--major "auto inc major" ).action(ArgAction::SetTrue)) |
| 11 | .arg(arg!(--minor "auto inc minor" ).action(ArgAction::SetTrue)) |
| 12 | .arg(arg!(--patch "auto inc patch" ).action(ArgAction::SetTrue)) |
| 13 | // Create a group, make it required, and add the above arguments |
| 14 | .group( |
| 15 | ArgGroup::new("vers" ) |
| 16 | .required(true) |
| 17 | .args(["set-ver" , "major" , "minor" , "patch" ]), |
| 18 | ) |
| 19 | // Arguments can also be added to a group individually, these two arguments |
| 20 | // are part of the "input" group which is not required |
| 21 | .arg( |
| 22 | arg!([INPUT_FILE] "some regular input" ) |
| 23 | .value_parser(value_parser!(PathBuf)) |
| 24 | .group("input" ), |
| 25 | ) |
| 26 | .arg( |
| 27 | arg!(--"spec-in" <SPEC_IN> "some special input argument" ) |
| 28 | .value_parser(value_parser!(PathBuf)) |
| 29 | .group("input" ), |
| 30 | ) |
| 31 | // Now let's assume we have a -c [config] argument which requires one of |
| 32 | // (but **not** both) the "input" arguments |
| 33 | .arg( |
| 34 | arg!(config: -c <CONFIG>) |
| 35 | .value_parser(value_parser!(PathBuf)) |
| 36 | .requires("input" ), |
| 37 | ) |
| 38 | .get_matches(); |
| 39 | |
| 40 | // Let's assume the old version 1.2.3 |
| 41 | let mut major = 1; |
| 42 | let mut minor = 2; |
| 43 | let mut patch = 3; |
| 44 | |
| 45 | // See if --set-ver was used to set the version manually |
| 46 | let version = if let Some(ver) = matches.get_one::<String>("set-ver" ) { |
| 47 | ver.to_owned() |
| 48 | } else { |
| 49 | // Increment the one requested (in a real program, we'd reset the lower numbers) |
| 50 | let (maj, min, pat) = ( |
| 51 | matches.get_flag("major" ), |
| 52 | matches.get_flag("minor" ), |
| 53 | matches.get_flag("patch" ), |
| 54 | ); |
| 55 | match (maj, min, pat) { |
| 56 | (true, _, _) => major += 1, |
| 57 | (_, true, _) => minor += 1, |
| 58 | (_, _, true) => patch += 1, |
| 59 | _ => unreachable!(), |
| 60 | }; |
| 61 | format!("{major}.{minor}.{patch}" ) |
| 62 | }; |
| 63 | |
| 64 | println!("Version: {version}" ); |
| 65 | |
| 66 | // Check for usage of -c |
| 67 | if matches.contains_id("config" ) { |
| 68 | let input = matches |
| 69 | .get_one::<PathBuf>("INPUT_FILE" ) |
| 70 | .unwrap_or_else(|| matches.get_one::<PathBuf>("spec-in" ).unwrap()) |
| 71 | .display(); |
| 72 | println!( |
| 73 | "Doing work using input {} and config {}" , |
| 74 | input, |
| 75 | matches.get_one::<PathBuf>("config" ).unwrap().display() |
| 76 | ); |
| 77 | } |
| 78 | } |
| 79 | |