please_clap/
lib.rs

1// DOCS
2
3/// Process a `clap::ArgMatches` with pattern-matching-like syntax.
4///
5/// ```
6/// # #[macro_use] extern crate please_clap;
7/// # extern crate clap;
8/// use self::clap::*;
9/// # fn main() {
10///    let matches = App::new("test")
11///        .subcommand(SubCommand::with_name("sub")
12///            .subcommand(SubCommand::with_name("subsub")
13///                .arg(Arg::with_name("TEST_ARG").index(1))))
14///        .subcommand(SubCommand::with_name("othersub"))
15///        .get_matches_from(vec!["test", "sub", "subsub", "fooarg"]);
16///
17///    let mut called = false;
18///    clap_dispatch!(matches; {
19///        sub(sub_matches) => clap_dispatch!(sub_matches; {
20///            subsub(_, TEST_ARG as test_arg) => {
21///                assert_eq!(test_arg, "fooarg");
22///                called = true;
23///            }
24///        }),
25///        othersub() => { panic!("Should not have been called."); }
26///    });
27///
28///    assert!(called);
29/// # }
30/// ```
31#[macro_export]
32macro_rules! clap_dispatch {
33    ($matches:expr; { $( $name:ident $match_arm_args:tt => $callback:expr ),* }) => {
34        match $matches.subcommand_name() {
35            $(
36                Some(stringify!($name)) => {
37                    let matches = $matches.subcommand_matches(stringify!($name)).unwrap();
38                    clap_dispatch!(MATCH_ARM_ARGS, matches, $match_arm_args);
39                    $callback;
40                }
41            )*
42            Some(x) => {
43                panic!("Internal error: Command not covered: {}", x);
44            },
45            None => {
46                println!("Subcommand required. See --help for help.");
47                ::std::process::exit(1);
48            }
49        }
50    };
51
52    (MATCH_ARM_ARGS, $matches:ident, ( $matches_name:pat, $($arg_name:ident as $varname:ident),* )) => {
53        $(
54            let $varname = $matches.value_of(stringify!($arg_name)).unwrap();
55        )*
56        let $matches_name = $matches;
57    };
58
59    // Transform `foo(_) => ()` into `foo(_,) => ()`
60    (MATCH_ARM_ARGS, $matches:ident, ( $matches_name:pat )) => { clap_dispatch!(MATCH_ARM_ARGS, $matches, ($matches_name,)) };
61
62    // Transform `foo() => ()` into `foo(_,) => ()`
63    (MATCH_ARM_ARGS, $matches:ident, ()) => { clap_dispatch!(MATCH_ARM_ARGS, $matches, (_,)) };
64
65}