119625d8cSopenharmony_ciuse clap::{Arg, ArgAction, ArgMatches, Command};
219625d8cSopenharmony_ci
319625d8cSopenharmony_cifn get_app() -> Command {
419625d8cSopenharmony_ci    Command::new("myprog")
519625d8cSopenharmony_ci        .arg(
619625d8cSopenharmony_ci            Arg::new("GLOBAL_ARG")
719625d8cSopenharmony_ci                .long("global-arg")
819625d8cSopenharmony_ci                .help("Specifies something needed by the subcommands")
919625d8cSopenharmony_ci                .global(true)
1019625d8cSopenharmony_ci                .action(ArgAction::Set)
1119625d8cSopenharmony_ci                .default_value("default_value"),
1219625d8cSopenharmony_ci        )
1319625d8cSopenharmony_ci        .arg(
1419625d8cSopenharmony_ci            Arg::new("GLOBAL_FLAG")
1519625d8cSopenharmony_ci                .long("global-flag")
1619625d8cSopenharmony_ci                .help("Specifies something needed by the subcommands")
1719625d8cSopenharmony_ci                .global(true)
1819625d8cSopenharmony_ci                .action(ArgAction::Count),
1919625d8cSopenharmony_ci        )
2019625d8cSopenharmony_ci        .subcommand(Command::new("outer").subcommand(Command::new("inner")))
2119625d8cSopenharmony_ci}
2219625d8cSopenharmony_ci
2319625d8cSopenharmony_cifn get_matches(cmd: Command, argv: &'static str) -> ArgMatches {
2419625d8cSopenharmony_ci    cmd.try_get_matches_from(argv.split(' ').collect::<Vec<_>>())
2519625d8cSopenharmony_ci        .unwrap()
2619625d8cSopenharmony_ci}
2719625d8cSopenharmony_ci
2819625d8cSopenharmony_cifn get_outer_matches(m: &ArgMatches) -> &ArgMatches {
2919625d8cSopenharmony_ci    m.subcommand_matches("outer")
3019625d8cSopenharmony_ci        .expect("could not access outer subcommand")
3119625d8cSopenharmony_ci}
3219625d8cSopenharmony_ci
3319625d8cSopenharmony_cifn get_inner_matches(m: &ArgMatches) -> &ArgMatches {
3419625d8cSopenharmony_ci    get_outer_matches(m)
3519625d8cSopenharmony_ci        .subcommand_matches("inner")
3619625d8cSopenharmony_ci        .expect("could not access inner subcommand")
3719625d8cSopenharmony_ci}
3819625d8cSopenharmony_ci
3919625d8cSopenharmony_cifn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
4019625d8cSopenharmony_ci    m.get_one::<String>("GLOBAL_ARG").map(|v| v.as_str()) == val.into()
4119625d8cSopenharmony_ci}
4219625d8cSopenharmony_ci
4319625d8cSopenharmony_cifn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
4419625d8cSopenharmony_ci    get_inner_matches(m)
4519625d8cSopenharmony_ci        .get_one::<String>("GLOBAL_ARG")
4619625d8cSopenharmony_ci        .map(|v| v.as_str())
4719625d8cSopenharmony_ci        == val.into()
4819625d8cSopenharmony_ci}
4919625d8cSopenharmony_ci
5019625d8cSopenharmony_cifn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches, val: T) -> bool {
5119625d8cSopenharmony_ci    get_outer_matches(m)
5219625d8cSopenharmony_ci        .get_one::<String>("GLOBAL_ARG")
5319625d8cSopenharmony_ci        .map(|v| v.as_str())
5419625d8cSopenharmony_ci        == val.into()
5519625d8cSopenharmony_ci}
5619625d8cSopenharmony_ci
5719625d8cSopenharmony_cifn top_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
5819625d8cSopenharmony_ci    (m.contains_id("GLOBAL_FLAG") == present)
5919625d8cSopenharmony_ci        && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
6019625d8cSopenharmony_ci}
6119625d8cSopenharmony_ci
6219625d8cSopenharmony_cifn inner_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
6319625d8cSopenharmony_ci    let m = get_inner_matches(m);
6419625d8cSopenharmony_ci    (m.contains_id("GLOBAL_FLAG") == present)
6519625d8cSopenharmony_ci        && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
6619625d8cSopenharmony_ci}
6719625d8cSopenharmony_ci
6819625d8cSopenharmony_cifn outer_can_access_flag(m: &ArgMatches, present: bool, occurrences: u8) -> bool {
6919625d8cSopenharmony_ci    let m = get_outer_matches(m);
7019625d8cSopenharmony_ci    (m.contains_id("GLOBAL_FLAG") == present)
7119625d8cSopenharmony_ci        && (m.get_one::<u8>("GLOBAL_FLAG").copied() == Some(occurrences))
7219625d8cSopenharmony_ci}
7319625d8cSopenharmony_ci
7419625d8cSopenharmony_ci#[test]
7519625d8cSopenharmony_cifn global_arg_used_top_level() {
7619625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog --global-arg=some_value outer inner");
7719625d8cSopenharmony_ci
7819625d8cSopenharmony_ci    assert!(top_can_access_arg(&m, "some_value"));
7919625d8cSopenharmony_ci    assert!(inner_can_access_arg(&m, "some_value"));
8019625d8cSopenharmony_ci    assert!(outer_can_access_arg(&m, "some_value"));
8119625d8cSopenharmony_ci}
8219625d8cSopenharmony_ci
8319625d8cSopenharmony_ci#[test]
8419625d8cSopenharmony_cifn global_arg_used_outer() {
8519625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer --global-arg=some_value inner");
8619625d8cSopenharmony_ci
8719625d8cSopenharmony_ci    assert!(top_can_access_arg(&m, "some_value"));
8819625d8cSopenharmony_ci    assert!(inner_can_access_arg(&m, "some_value"));
8919625d8cSopenharmony_ci    assert!(outer_can_access_arg(&m, "some_value"));
9019625d8cSopenharmony_ci}
9119625d8cSopenharmony_ci
9219625d8cSopenharmony_ci#[test]
9319625d8cSopenharmony_cifn global_arg_used_inner() {
9419625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer inner --global-arg=some_value");
9519625d8cSopenharmony_ci
9619625d8cSopenharmony_ci    assert!(top_can_access_arg(&m, "some_value"));
9719625d8cSopenharmony_ci    assert!(inner_can_access_arg(&m, "some_value"));
9819625d8cSopenharmony_ci    assert!(outer_can_access_arg(&m, "some_value"));
9919625d8cSopenharmony_ci}
10019625d8cSopenharmony_ci
10119625d8cSopenharmony_ci#[test]
10219625d8cSopenharmony_cifn global_arg_default_value() {
10319625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer inner");
10419625d8cSopenharmony_ci
10519625d8cSopenharmony_ci    assert!(top_can_access_arg(&m, "default_value"));
10619625d8cSopenharmony_ci    assert!(inner_can_access_arg(&m, "default_value"));
10719625d8cSopenharmony_ci    assert!(outer_can_access_arg(&m, "default_value"));
10819625d8cSopenharmony_ci}
10919625d8cSopenharmony_ci
11019625d8cSopenharmony_ci#[test]
11119625d8cSopenharmony_cifn global_flag_used_top_level() {
11219625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog --global-flag outer inner");
11319625d8cSopenharmony_ci
11419625d8cSopenharmony_ci    assert!(top_can_access_flag(&m, true, 1));
11519625d8cSopenharmony_ci    assert!(inner_can_access_flag(&m, true, 1));
11619625d8cSopenharmony_ci    assert!(outer_can_access_flag(&m, true, 1));
11719625d8cSopenharmony_ci}
11819625d8cSopenharmony_ci
11919625d8cSopenharmony_ci#[test]
12019625d8cSopenharmony_cifn global_flag_used_outer() {
12119625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer --global-flag inner");
12219625d8cSopenharmony_ci
12319625d8cSopenharmony_ci    assert!(top_can_access_flag(&m, true, 1));
12419625d8cSopenharmony_ci    assert!(inner_can_access_flag(&m, true, 1));
12519625d8cSopenharmony_ci    assert!(outer_can_access_flag(&m, true, 1));
12619625d8cSopenharmony_ci}
12719625d8cSopenharmony_ci
12819625d8cSopenharmony_ci#[test]
12919625d8cSopenharmony_cifn global_flag_used_inner() {
13019625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer inner --global-flag");
13119625d8cSopenharmony_ci
13219625d8cSopenharmony_ci    assert!(top_can_access_flag(&m, true, 1));
13319625d8cSopenharmony_ci    assert!(inner_can_access_flag(&m, true, 1));
13419625d8cSopenharmony_ci    assert!(outer_can_access_flag(&m, true, 1));
13519625d8cSopenharmony_ci}
13619625d8cSopenharmony_ci
13719625d8cSopenharmony_ci#[test]
13819625d8cSopenharmony_cifn global_flag_2x_used_top_level() {
13919625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog --global-flag --global-flag outer inner");
14019625d8cSopenharmony_ci
14119625d8cSopenharmony_ci    assert!(top_can_access_flag(&m, true, 2));
14219625d8cSopenharmony_ci    assert!(inner_can_access_flag(&m, true, 2));
14319625d8cSopenharmony_ci    assert!(outer_can_access_flag(&m, true, 2));
14419625d8cSopenharmony_ci}
14519625d8cSopenharmony_ci
14619625d8cSopenharmony_ci#[test]
14719625d8cSopenharmony_cifn global_flag_2x_used_inner() {
14819625d8cSopenharmony_ci    let m = get_matches(get_app(), "myprog outer inner --global-flag --global-flag");
14919625d8cSopenharmony_ci
15019625d8cSopenharmony_ci    assert!(top_can_access_flag(&m, true, 2));
15119625d8cSopenharmony_ci    assert!(inner_can_access_flag(&m, true, 2));
15219625d8cSopenharmony_ci    assert!(outer_can_access_flag(&m, true, 2));
15319625d8cSopenharmony_ci}
154