04_03_relations_derive/
04_03_relations.rs

1use clap::{Args, Parser};
2
3#[derive(Parser)]
4#[command(version, about, long_about = None)]
5struct Cli {
6    #[command(flatten)]
7    vers: Vers,
8
9    /// some regular input
10    #[arg(group = "input")]
11    input_file: Option<String>,
12
13    /// some special input argument
14    #[arg(long, group = "input")]
15    spec_in: Option<String>,
16
17    #[arg(short, requires = "input")]
18    config: Option<String>,
19}
20
21#[derive(Args)]
22#[group(required = true, multiple = false)]
23struct Vers {
24    /// set version manually
25    #[arg(long, value_name = "VER")]
26    set_ver: Option<String>,
27
28    /// auto inc major
29    #[arg(long)]
30    major: bool,
31
32    /// auto inc minor
33    #[arg(long)]
34    minor: bool,
35
36    /// auto inc patch
37    #[arg(long)]
38    patch: bool,
39}
40
41fn main() {
42    let cli = Cli::parse();
43
44    // Let's assume the old version 1.2.3
45    let mut major = 1;
46    let mut minor = 2;
47    let mut patch = 3;
48
49    // See if --set_ver was used to set the version manually
50    let vers = &cli.vers;
51    let version = if let Some(ver) = vers.set_ver.as_deref() {
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) = (vers.major, vers.minor, vers.patch);
56        match (maj, min, pat) {
57            (true, _, _) => major += 1,
58            (_, true, _) => minor += 1,
59            (_, _, true) => patch += 1,
60            _ => unreachable!(),
61        };
62        format!("{major}.{minor}.{patch}")
63    };
64
65    println!("Version: {version}");
66
67    // Check for usage of -c
68    if let Some(config) = cli.config.as_deref() {
69        let input = cli
70            .input_file
71            .as_deref()
72            .unwrap_or_else(|| cli.spec_in.as_deref().unwrap());
73        println!("Doing work using input {input} and config {config}");
74    }
75}