1use clap::error::ErrorKind;
2use clap::{CommandFactory, Parser};
3
4#[derive(Parser)]
5#[command(author, version, about, long_about = None)]
6struct Cli {
7 /// set version manually
8 #[arg(long, value_name = "VER")]
9 set_ver: Option<String>,
10
11 /// auto inc major
12 #[arg(long)]
13 major: bool,
14
15 /// auto inc minor
16 #[arg(long)]
17 minor: bool,
18
19 /// auto inc patch
20 #[arg(long)]
21 patch: bool,
22
23 /// some regular input
24 input_file: Option<String>,
25
26 /// some special input argument
27 #[arg(long)]
28 spec_in: Option<String>,
29
30 #[arg(short)]
31 config: Option<String>,
32}
33
34fn main() {
35 let cli = Cli::parse();
36
37 // Let's assume the old version 1.2.3
38 let mut major = 1;
39 let mut minor = 2;
40 let mut patch = 3;
41
42 // See if --set-ver was used to set the version manually
43 let version = if let Some(ver) = cli.set_ver.as_deref() {
44 if cli.major || cli.minor || cli.patch {
45 let mut cmd = Cli::command();
46 cmd.error(
47 ErrorKind::ArgumentConflict,
48 "Can't do relative and absolute version change",
49 )
50 .exit();
51 }
52 ver.to_string()
53 } else {
54 // Increment the one requested (in a real program, we'd reset the lower numbers)
55 let (maj, min, pat) = (cli.major, cli.minor, cli.patch);
56 match (maj, min, pat) {
57 (true, false, false) => major += 1,
58 (false, true, false) => minor += 1,
59 (false, false, true) => patch += 1,
60 _ => {
61 let mut cmd = Cli::command();
62 cmd.error(
63 ErrorKind::ArgumentConflict,
64 "Can only modify one version field",
65 )
66 .exit();
67 }
68 };
69 format!("{major}.{minor}.{patch}")
70 };
71
72 println!("Version: {version}");
73
74 // Check for usage of -c
75 if let Some(config) = cli.config.as_deref() {
76 let input = cli
77 .input_file
78 .as_deref()
79 // 'or' is preferred to 'or_else' here since `Option::as_deref` is 'const'
80 .or(cli.spec_in.as_deref())
81 .unwrap_or_else(|| {
82 let mut cmd = Cli::command();
83 cmd.error(
84 ErrorKind::MissingRequiredArgument,
85 "INPUT_FILE or --spec-in is required when using --config",
86 )
87 .exit()
88 });
89 println!("Doing work using input {input} and config {config}");
90 }
91}
92