mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 14:52:33 +00:00
commit
7372359c9c
93 changed files with 6821 additions and 6891 deletions
|
@ -23,6 +23,7 @@ appveyor = { repository = "kbknapp/clap-rs" }
|
|||
bitflags = "1.0"
|
||||
unicode-width = "0.1.4"
|
||||
textwrap = "0.9.0"
|
||||
ordermap = "0.3.5"
|
||||
strsim = { version = "0.7.0", optional = true }
|
||||
ansi_term = { version = "0.10.0", optional = true }
|
||||
yaml-rust = { version = "0.3.5", optional = true }
|
||||
|
|
19
TODO.md
Normal file
19
TODO.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
- [ ] update-todo.sh
|
||||
- [ ] src/lib.rs
|
||||
-[ ] 578:@TODO @release @docs
|
||||
-[ ] 580:@TODO @release @docs
|
||||
-[ ] 583:@TODO @release @docs
|
||||
-[ ] 592:@TODO @release @docs
|
||||
-[ ] 598:@TODO @release @docs
|
||||
-[ ] 608:@TODO @release @docs
|
||||
-[ ] 610:@TODO @release @docs
|
||||
-[ ] 614:@TODO @release @docs
|
||||
-[ ] 616:@TODO @release @docs
|
||||
-[ ] 619:@TODO @release @docs
|
||||
-[ ] 623:@TODO @release @docs
|
||||
- [ ] src/app/parser.rs
|
||||
-[ ] 678:@TODO @perf: cloning all these Apps ins't great, but since it's just displaying the help
|
||||
- [ ] src/app/mod.rs
|
||||
-[ ] 1760:@TODO @v3-alpha @perf: should only propagate globals to subcmd we find, or for help
|
||||
- [ ] src/args/arg.rs
|
||||
-[ ] 3545:@TODO @p2 @docs @release: write docs
|
|
@ -8,11 +8,7 @@ use clap::App;
|
|||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn build_app(b: &mut Bencher) {
|
||||
b.iter(|| App::new("claptests"));
|
||||
}
|
||||
fn build_app(b: &mut Bencher) { b.iter(|| App::new("claptests")); }
|
||||
|
||||
#[bench]
|
||||
fn parse_clean(b: &mut Bencher) {
|
||||
b.iter(|| App::new("claptests").get_matches_from(vec![""]));
|
||||
}
|
||||
fn parse_clean(b: &mut Bencher) { b.iter(|| App::new("claptests").get_matches_from(vec![""])); }
|
||||
|
|
|
@ -20,25 +20,18 @@ macro_rules! create_app {
|
|||
}
|
||||
|
||||
#[bench]
|
||||
fn build_app(b: &mut Bencher) {
|
||||
|
||||
b.iter(|| create_app!());
|
||||
}
|
||||
fn build_app(b: &mut Bencher) { b.iter(|| create_app!()); }
|
||||
|
||||
#[bench]
|
||||
fn add_flag(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| build_app().arg(Arg::from_usage("-s, --some 'something'")));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn add_flag_ref(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| {
|
||||
let arg = Arg::from_usage("-s, --some 'something'");
|
||||
|
@ -48,18 +41,14 @@ fn add_flag_ref(b: &mut Bencher) {
|
|||
|
||||
#[bench]
|
||||
fn add_opt(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| build_app().arg(Arg::from_usage("-s, --some <FILE> 'something'")));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn add_opt_ref(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| {
|
||||
let arg = Arg::from_usage("-s, --some <FILE> 'something'");
|
||||
|
@ -69,18 +58,14 @@ fn add_opt_ref(b: &mut Bencher) {
|
|||
|
||||
#[bench]
|
||||
fn add_pos(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| build_app().arg(Arg::with_name("some")));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn add_pos_ref(b: &mut Bencher) {
|
||||
fn build_app() -> App<'static, 'static> {
|
||||
App::new("claptests")
|
||||
}
|
||||
fn build_app() -> App<'static, 'static> { App::new("claptests") }
|
||||
|
||||
b.iter(|| {
|
||||
let arg = Arg::with_name("some");
|
||||
|
@ -89,14 +74,10 @@ fn add_pos_ref(b: &mut Bencher) {
|
|||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_clean(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec![""]));
|
||||
}
|
||||
fn parse_clean(b: &mut Bencher) { b.iter(|| create_app!().get_matches_from(vec![""])); }
|
||||
|
||||
#[bench]
|
||||
fn parse_flag(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"]));
|
||||
}
|
||||
fn parse_flag(b: &mut Bencher) { b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"])); }
|
||||
|
||||
#[bench]
|
||||
fn parse_option(b: &mut Bencher) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
extern crate clap;
|
||||
extern crate test;
|
||||
|
||||
use clap::{App, Arg, SubCommand, AppSettings};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
|
@ -43,94 +43,121 @@ macro_rules! create_app {
|
|||
}
|
||||
|
||||
#[bench]
|
||||
fn create_app_from_usage(b: &mut Bencher) {
|
||||
|
||||
b.iter(|| create_app!());
|
||||
}
|
||||
fn create_app_from_usage(b: &mut Bencher) { b.iter(|| create_app!()); }
|
||||
|
||||
#[bench]
|
||||
fn create_app_builder(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
App::new("claptests")
|
||||
.version("0.1")
|
||||
.about("tests clap library")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(Arg::with_name("opt")
|
||||
.version("0.1")
|
||||
.about("tests clap library")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
.help("tests options")
|
||||
.short("o")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.multiple(true))
|
||||
.arg(Arg::with_name("positional")
|
||||
.multiple(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("positional")
|
||||
.help("tests positionals")
|
||||
.index(1))
|
||||
.arg(Arg::with_name("flag")
|
||||
.short("f")
|
||||
.help("tests flags")
|
||||
.long("flag")
|
||||
.multiple(true)
|
||||
.global(true))
|
||||
.arg(Arg::with_name("flag2")
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("flag")
|
||||
.short("f")
|
||||
.help("tests flags")
|
||||
.long("flag")
|
||||
.multiple(true)
|
||||
.global(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("flag2")
|
||||
.short("F")
|
||||
.help("tests flags with exclusions")
|
||||
.conflicts_with("flag")
|
||||
.requires("option2"))
|
||||
.arg(Arg::with_name("option2")
|
||||
.requires("option2"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("option2")
|
||||
.help("tests long options with exclusions")
|
||||
.conflicts_with("option")
|
||||
.requires("positional2")
|
||||
.takes_value(true)
|
||||
.long("long-option-2"))
|
||||
.arg(Arg::with_name("positional2")
|
||||
.long("long-option-2"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("positional2")
|
||||
.index(3)
|
||||
.help("tests positionals with exclusions"))
|
||||
.arg(Arg::with_name("option3")
|
||||
.help("tests positionals with exclusions"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("option3")
|
||||
.short("O")
|
||||
.long("Option")
|
||||
.takes_value(true)
|
||||
.help("tests options with specific value sets")
|
||||
.possible_values(&OPT3_VALS))
|
||||
.arg(Arg::with_name("positional3")
|
||||
.possible_values(&OPT3_VALS),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("positional3")
|
||||
.multiple(true)
|
||||
.help("tests positionals with specific values")
|
||||
.index(4)
|
||||
.possible_values(&POS3_VALS))
|
||||
.arg(Arg::with_name("multvals")
|
||||
.possible_values(&POS3_VALS),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("multvals")
|
||||
.long("multvals")
|
||||
.takes_value(true)
|
||||
.help("Tests mutliple values, not mult occs")
|
||||
.value_names(&["one", "two"]))
|
||||
.arg(Arg::with_name("multvalsmo")
|
||||
.value_names(&["one", "two"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("multvalsmo")
|
||||
.long("multvalsmo")
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.help("Tests mutliple values, not mult occs")
|
||||
.value_names(&["one", "two"]))
|
||||
.arg(Arg::with_name("minvals")
|
||||
.value_names(&["one", "two"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("minvals")
|
||||
.long("minvals2")
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.help("Tests 2 min vals")
|
||||
.min_values(2))
|
||||
.arg(Arg::with_name("maxvals")
|
||||
.min_values(2),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("maxvals")
|
||||
.long("maxvals3")
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.help("Tests 3 max vals")
|
||||
.max_values(3))
|
||||
.subcommand(SubCommand::with_name("subcmd")
|
||||
.max_values(3),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("subcmd")
|
||||
.about("tests subcommands")
|
||||
.version("0.1")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(Arg::with_name("scoption")
|
||||
.short("o")
|
||||
.long("option")
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.help("tests options"))
|
||||
.arg(Arg::with_name("scpositional")
|
||||
.index(1)
|
||||
.help("tests positionals")));
|
||||
.arg(
|
||||
Arg::with_name("scoption")
|
||||
.short("o")
|
||||
.long("option")
|
||||
.multiple(true)
|
||||
.takes_value(true)
|
||||
.help("tests options"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("scpositional")
|
||||
.index(1)
|
||||
.help("tests positionals"),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -170,14 +197,10 @@ fn create_app_macros(b: &mut Bencher) {
|
|||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_clean(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec![""]));
|
||||
}
|
||||
fn parse_clean(b: &mut Bencher) { b.iter(|| create_app!().get_matches_from(vec![""])); }
|
||||
|
||||
#[bench]
|
||||
fn parse_flag(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"]));
|
||||
}
|
||||
fn parse_flag(b: &mut Bencher) { b.iter(|| create_app!().get_matches_from(vec!["myprog", "-f"])); }
|
||||
|
||||
#[bench]
|
||||
fn parse_option(b: &mut Bencher) {
|
||||
|
@ -211,20 +234,75 @@ fn parse_sc_positional(b: &mut Bencher) {
|
|||
|
||||
#[bench]
|
||||
fn parse_complex1(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec!["myprog", "-ff", "-o", "option1", "arg1", "-O", "fast", "arg2", "--multvals", "one", "two", "emacs"]));
|
||||
b.iter(|| {
|
||||
create_app!().get_matches_from(vec![
|
||||
"myprog",
|
||||
"-ff",
|
||||
"-o",
|
||||
"option1",
|
||||
"arg1",
|
||||
"-O",
|
||||
"fast",
|
||||
"arg2",
|
||||
"--multvals",
|
||||
"one",
|
||||
"two",
|
||||
"emacs",
|
||||
])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_complex2(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
|
||||
b.iter(|| {
|
||||
create_app!().get_matches_from(vec![
|
||||
"myprog",
|
||||
"arg1",
|
||||
"-f",
|
||||
"arg2",
|
||||
"--long-option-2",
|
||||
"some",
|
||||
"-O",
|
||||
"slow",
|
||||
"--multvalsmo",
|
||||
"one",
|
||||
"two",
|
||||
"--minvals2",
|
||||
"3",
|
||||
"2",
|
||||
"1",
|
||||
])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_complex2_with_args_negate_scs(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().setting(AppSettings::ArgsNegateSubcommands).get_matches_from(vec!["myprog", "arg1", "-f", "arg2", "--long-option-2", "some", "-O", "slow", "--multvalsmo", "one", "two", "--minvals2", "3", "2", "1"]));
|
||||
b.iter(|| {
|
||||
create_app!()
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.get_matches_from(vec![
|
||||
"myprog",
|
||||
"arg1",
|
||||
"-f",
|
||||
"arg2",
|
||||
"--long-option-2",
|
||||
"some",
|
||||
"-O",
|
||||
"slow",
|
||||
"--multvalsmo",
|
||||
"one",
|
||||
"two",
|
||||
"--minvals2",
|
||||
"3",
|
||||
"2",
|
||||
"1",
|
||||
])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_sc_complex(b: &mut Bencher) {
|
||||
b.iter(|| create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"]));
|
||||
b.iter(|| {
|
||||
create_app!().get_matches_from(vec!["myprog", "subcmd", "-f", "-o", "option1", "arg1"])
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::io::Cursor;
|
|||
use clap::App;
|
||||
use clap::{Arg, SubCommand};
|
||||
|
||||
fn build_help(app: &App) -> String {
|
||||
fn build_help(app: &mut App) -> String {
|
||||
let mut buf = Cursor::new(Vec::with_capacity(50));
|
||||
app.write_help(&mut buf).unwrap();
|
||||
let content = buf.into_inner();
|
||||
|
@ -22,12 +22,16 @@ fn app_example1<'b, 'c>() -> App<'b, 'c> {
|
|||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.args_from_usage("-c, --config=[FILE] 'Sets a custom config file'
|
||||
.args_from_usage(
|
||||
"-c, --config=[FILE] 'Sets a custom config file'
|
||||
<output> 'Sets an optional output file'
|
||||
-d... 'Turn debugging information on'")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"))
|
||||
-d... 'Turn debugging information on'",
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example2<'b, 'c>() -> App<'b, 'c> {
|
||||
|
@ -39,21 +43,27 @@ fn app_example2<'b, 'c>() -> App<'b, 'c> {
|
|||
|
||||
fn app_example3<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("MyApp")
|
||||
.arg(Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d"))
|
||||
.args(&[Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.takes_value(true)
|
||||
.short("c")
|
||||
.long("config"),
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true)])
|
||||
.arg(
|
||||
Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d"),
|
||||
)
|
||||
.args(&[
|
||||
Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.takes_value(true)
|
||||
.short("c")
|
||||
.long("config"),
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true),
|
||||
])
|
||||
.arg_from_usage("--license 'display the license file'")
|
||||
.args_from_usage("[output] 'Supply an output file to use'
|
||||
-i, --int=[IFACE] 'Set an interface to use'")
|
||||
.args_from_usage(
|
||||
"[output] 'Supply an output file to use'
|
||||
-i, --int=[IFACE] 'Set an interface to use'",
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example4<'b, 'c>() -> App<'b, 'c> {
|
||||
|
@ -61,138 +71,154 @@ fn app_example4<'b, 'c>() -> App<'b, 'c> {
|
|||
.about("Parses an input file to do awesome things")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d")
|
||||
.long("debug"))
|
||||
.arg(Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.short("c")
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true))
|
||||
.arg(
|
||||
Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d")
|
||||
.long("debug"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.short("c")
|
||||
.long("config"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example5<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("MyApp").arg(Arg::with_name("awesome")
|
||||
.help("turns up the awesome")
|
||||
.short("a")
|
||||
.long("awesome")
|
||||
.multiple(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"))
|
||||
App::new("MyApp").arg(
|
||||
Arg::with_name("awesome")
|
||||
.help("turns up the awesome")
|
||||
.short("a")
|
||||
.long("awesome")
|
||||
.multiple(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example6<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("MyApp")
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.requires("config")
|
||||
.conflicts_with("output")
|
||||
.required(true))
|
||||
.arg(Arg::with_name("config")
|
||||
.help("the config file to use")
|
||||
.index(2))
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.requires("config")
|
||||
.conflicts_with("output")
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.help("the config file to use")
|
||||
.index(2),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example7<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("MyApp")
|
||||
.arg(Arg::with_name("config"))
|
||||
.arg(Arg::with_name("output"))
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.takes_value(true)
|
||||
.short("i")
|
||||
.long("input")
|
||||
.multiple(true)
|
||||
.required(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"))
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.takes_value(true)
|
||||
.short("i")
|
||||
.long("input")
|
||||
.multiple(true)
|
||||
.required(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example8<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("MyApp")
|
||||
.arg(Arg::with_name("config"))
|
||||
.arg(Arg::with_name("output"))
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.takes_value(true)
|
||||
.short("i")
|
||||
.long("input")
|
||||
.multiple(true)
|
||||
.required(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"))
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.takes_value(true)
|
||||
.short("i")
|
||||
.long("input")
|
||||
.multiple(true)
|
||||
.required(true)
|
||||
.requires("config")
|
||||
.conflicts_with("output"),
|
||||
)
|
||||
}
|
||||
|
||||
fn app_example10<'b, 'c>() -> App<'b, 'c> {
|
||||
App::new("myapp")
|
||||
.about("does awesome things")
|
||||
.arg(Arg::with_name("CONFIG")
|
||||
App::new("myapp").about("does awesome things").arg(
|
||||
Arg::with_name("CONFIG")
|
||||
.help("The config file to use (default is \"config.json\")")
|
||||
.short("c")
|
||||
.takes_value(true))
|
||||
.takes_value(true),
|
||||
)
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example1(b: &mut Bencher) {
|
||||
let app = app_example1();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example1();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example2(b: &mut Bencher) {
|
||||
let app = app_example2();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example2();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example3(b: &mut Bencher) {
|
||||
let app = app_example3();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example3();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example4(b: &mut Bencher) {
|
||||
let app = app_example4();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example4();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example5(b: &mut Bencher) {
|
||||
let app = app_example5();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example5();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example6(b: &mut Bencher) {
|
||||
let app = app_example6();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example6();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example7(b: &mut Bencher) {
|
||||
let app = app_example7();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example7();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example8(b: &mut Bencher) {
|
||||
let app = app_example8();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example8();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example10(b: &mut Bencher) {
|
||||
let app = app_example10();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example10();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn example4_template(b: &mut Bencher) {
|
||||
let app = app_example4().template("{bin} {version}\n{author}\n{about}\n\nUSAGE:\n {usage}\n\nFLAGS:\n{flags}\n\nARGS:\n{args}\n");
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_example4().template("{bin} {version}\n{author}\n{about}\n\nUSAGE:\n {usage}\n\nFLAGS:\n{flags}\n\nARGS:\n{args}\n");
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
#![feature(test)]
|
||||
|
||||
extern crate clap;
|
||||
extern crate test;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate test;
|
||||
|
||||
use clap::{App, AppSettings, Arg, ArgSettings};
|
||||
|
||||
|
@ -24,14 +24,14 @@ fn build_app_long(b: &mut Bencher) { b.iter(|| app_long()); }
|
|||
|
||||
#[bench]
|
||||
fn build_help_short(b: &mut Bencher) {
|
||||
let app = app_short();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_short();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn build_help_long(b: &mut Bencher) {
|
||||
let app = app_long();
|
||||
b.iter(|| build_help(&app));
|
||||
let mut app = app_long();
|
||||
b.iter(|| build_help(&mut app));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
@ -40,244 +40,187 @@ fn parse_clean(b: &mut Bencher) { b.iter(|| app_short().get_matches_from(vec!["r
|
|||
#[bench]
|
||||
fn parse_complex(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
app_short().get_matches_from(vec!["rg",
|
||||
"pat",
|
||||
"-cFlN",
|
||||
"-pqr=some",
|
||||
"--null",
|
||||
"--no-filename",
|
||||
"--no-messages",
|
||||
"-SH",
|
||||
"-C5",
|
||||
"--follow",
|
||||
"-e some"])
|
||||
app_short().get_matches_from(vec![
|
||||
"rg",
|
||||
"pat",
|
||||
"-cFlN",
|
||||
"-pqr=some",
|
||||
"--null",
|
||||
"--no-filename",
|
||||
"--no-messages",
|
||||
"-SH",
|
||||
"-C5",
|
||||
"--follow",
|
||||
"-e some",
|
||||
])
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn parse_lots(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
app_short()
|
||||
.get_matches_from(vec!["rg", "pat", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some"])
|
||||
app_short().get_matches_from(vec![
|
||||
"rg", "pat", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
])
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -317,16 +260,14 @@ pub fn app_short() -> App<'static, 'static> { app(false, |k| USAGES[k].short) }
|
|||
/// Build a clap application with long help strings.
|
||||
pub fn app_long() -> App<'static, 'static> { app(true, |k| USAGES[k].long) }
|
||||
|
||||
|
||||
/// Build the help text of an application.
|
||||
fn build_help(app: &App) -> String {
|
||||
fn build_help(app: &mut App) -> String {
|
||||
let mut buf = Cursor::new(Vec::with_capacity(50));
|
||||
app.write_help(&mut buf).unwrap();
|
||||
let content = buf.into_inner();
|
||||
String::from_utf8(content).unwrap()
|
||||
}
|
||||
|
||||
|
||||
/// Build a clap application parameterized by usage strings.
|
||||
///
|
||||
/// The function given should take a clap argument name and return a help
|
||||
|
@ -335,9 +276,14 @@ fn build_help(app: &App) -> String {
|
|||
/// This is an intentionally stand-alone module so that it can be used easily
|
||||
/// in a `build.rs` script to build shell completion files.
|
||||
fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
|
||||
where F: Fn(&'static str) -> &'static str
|
||||
where
|
||||
F: Fn(&'static str) -> &'static str,
|
||||
{
|
||||
let arg = |name| Arg::with_name(name).help(doc(name)).next_line_help(next_line_help);
|
||||
let arg = |name| {
|
||||
Arg::with_name(name)
|
||||
.help(doc(name))
|
||||
.next_line_help(next_line_help)
|
||||
};
|
||||
let flag = |name| arg(name).long(name);
|
||||
|
||||
App::new("ripgrep")
|
||||
|
@ -773,5 +719,7 @@ lazy_static! {
|
|||
}
|
||||
|
||||
fn validate_number(s: String) -> Result<(), String> {
|
||||
s.parse::<usize>().map(|_| ()).map_err(|err| err.to_string())
|
||||
s.parse::<usize>()
|
||||
.map(|_| ())
|
||||
.map_err(|err| err.to_string())
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
extern crate clap;
|
||||
extern crate test;
|
||||
|
||||
use clap::{App, AppSettings, Arg, Shell, SubCommand, ArgGroup};
|
||||
use clap::{App, AppSettings, Arg, ArgGroup, Shell, SubCommand};
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
|
|
|
@ -36,9 +36,11 @@ mod test {
|
|||
err.write_to(&mut buf).unwrap();
|
||||
let content = buf.into_inner();
|
||||
let left = String::from_utf8(content).unwrap();
|
||||
assert_eq!(stderr, err.use_stderr());
|
||||
assert_eq!(stderr, err.use_stderr(),
|
||||
"Should Use STDERR failed. Should be {} but is {}", stderr, err.use_stderr());
|
||||
compare(left, right)
|
||||
}
|
||||
|
||||
pub fn compare_output2(l: App, args: &str, right1: &str, right2: &str, stderr: bool) -> bool {
|
||||
let mut buf = Cursor::new(Vec::with_capacity(50));
|
||||
let res = l.get_matches_from_safe(args.split(' ').collect::<Vec<_>>());
|
||||
|
|
17
etc/count-tests.sh
Executable file
17
etc/count-tests.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
IFS=$'\n'
|
||||
|
||||
touch .tmp.out
|
||||
|
||||
echo -n "Testing"
|
||||
for TEST in $(find tests/ -type f -name "*.rs" -exec basename {} .rs \;); do
|
||||
echo -n "."
|
||||
echo -n -e "$TEST:\t" >> .tmp.out
|
||||
cargo test --test $TEST 2>&1 | grep -o -e '[0-9]* failed;' >> .tmp.out
|
||||
done
|
||||
|
||||
echo "Done"
|
||||
column -t < .tmp.out
|
||||
rm .tmp.out
|
||||
unset IFS
|
18
etc/update-todo.sh
Executable file
18
etc/update-todo.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
rg -h 1>/dev/null || (echo "ripgrep not found" && false)
|
||||
|
||||
IFS=$'\n'
|
||||
|
||||
mv TODO.md TODO.bak || true
|
||||
touch TODO.md
|
||||
|
||||
for FILE in $(rg '@TODO' --ignore-file='update-todo.sh' --files-with-matches); do
|
||||
echo "- [ ] $FILE" >> TODO.md
|
||||
for LINE in $(rg -noe '@TODO([ @a-zA-Z-]+):?(.*)$' $FILE); do
|
||||
echo " -[ ] $LINE" >> TODO.md
|
||||
done;
|
||||
done;
|
||||
unset IFS
|
||||
|
||||
rm TODO.bak || true
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, SubCommand};
|
||||
|
||||
fn main() {
|
||||
|
||||
// This example shows how to create an application with several arguments using usage strings, which can be
|
||||
// far less verbose that shown in 01b_QuickExample.rs, but is more readable. The downside is you cannot set
|
||||
// the more advanced configuration options using this method (well...actually you can, you'll see ;) )
|
||||
|
@ -33,16 +32,20 @@ fn main() {
|
|||
// - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own)
|
||||
// + Used by "$ myapp help" (same functionality as "-h" or "--help")
|
||||
let matches = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.args_from_usage("-c, --config=[FILE] 'Sets a custom config file'
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.args_from_usage(
|
||||
"-c, --config=[FILE] 'Sets a custom config file'
|
||||
<output> 'Sets an optional output file'
|
||||
-d... 'Turn debugging information on'")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"))
|
||||
.get_matches();
|
||||
-d... 'Turn debugging information on'",
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// You can check the value provided by positional arguments, or option arguments
|
||||
if let Some(o) = matches.value_of("output") {
|
||||
|
@ -60,20 +63,19 @@ fn main() {
|
|||
1 => println!("Debug mode is kind of on"),
|
||||
2 => println!("Debug mode is on"),
|
||||
3 | _ => println!("Don't be crazy"),
|
||||
}
|
||||
}
|
||||
|
||||
// You can check for the existence of subcommands, and if found use their
|
||||
// matches just as you would the top level app
|
||||
if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
// "$ myapp test" was run
|
||||
if matches.is_present("list") {
|
||||
// "$ myapp test -l" was run
|
||||
println!("Printing testing lists...");
|
||||
} else {
|
||||
println!("Not printing testing lists...");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
// "$ myapp test" was run
|
||||
if matches.is_present("list") {
|
||||
// "$ myapp test -l" was run
|
||||
println!("Printing testing lists...");
|
||||
} else {
|
||||
println!("Not printing testing lists...");
|
||||
}
|
||||
}
|
||||
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg, SubCommand};
|
||||
|
||||
fn main() {
|
||||
|
||||
// This method shows the traditional, and slightly more configurable way to set up arguments. This method is
|
||||
// more verbose, but allows setting more configuration options, and even supports easier dynamic generation.
|
||||
//
|
||||
|
@ -35,28 +34,34 @@ fn main() {
|
|||
// - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own)
|
||||
// + Used by "$ myapp help" (same functionality as "-h" or "--help")
|
||||
let matches = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.arg(Arg::with_name("config")
|
||||
.short("c")
|
||||
.long("config")
|
||||
.value_name("FILE")
|
||||
.help("Sets a custom config file")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("output")
|
||||
.help("Sets an optional output file")
|
||||
.index(1))
|
||||
.arg(Arg::with_name("debug")
|
||||
.short("d")
|
||||
.multiple(true)
|
||||
.help("Turn debugging information on"))
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg(Arg::with_name("list")
|
||||
.short("l")
|
||||
.help("lists test values")))
|
||||
.get_matches();
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.short("c")
|
||||
.long("config")
|
||||
.value_name("FILE")
|
||||
.help("Sets a custom config file")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("output")
|
||||
.help("Sets an optional output file")
|
||||
.index(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("debug")
|
||||
.short("d")
|
||||
.multiple(true)
|
||||
.help("Turn debugging information on"),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg(Arg::with_name("list").short("l").help("lists test values")),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// You can check the value provided by positional arguments, or option arguments
|
||||
if let Some(o) = matches.value_of("output") {
|
||||
|
@ -74,20 +79,19 @@ fn main() {
|
|||
1 => println!("Debug mode is kind of on"),
|
||||
2 => println!("Debug mode is on"),
|
||||
3 | _ => println!("Don't be crazy"),
|
||||
}
|
||||
}
|
||||
|
||||
// You can check for the existence of subcommands, and if found use their
|
||||
// matches just as you would the top level app
|
||||
if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
// "$ myapp test" was run
|
||||
if matches.is_present("list") {
|
||||
// "$ myapp test -l" was run
|
||||
println!("Printing testing lists...");
|
||||
} else {
|
||||
println!("Not printing testing lists...");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
// "$ myapp test" was run
|
||||
if matches.is_present("list") {
|
||||
// "$ myapp test -l" was run
|
||||
println!("Printing testing lists...");
|
||||
} else {
|
||||
println!("Not printing testing lists...");
|
||||
}
|
||||
}
|
||||
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
|
@ -65,7 +65,14 @@ fn main() {
|
|||
// an example, and may be somewhat contrived
|
||||
//
|
||||
// First we check if debugging should be on or not
|
||||
println!("Debugging mode is: {}", if matches.is_present("debug") { "ON" } else { "OFF" });
|
||||
println!(
|
||||
"Debugging mode is: {}",
|
||||
if matches.is_present("debug") {
|
||||
"ON"
|
||||
} else {
|
||||
"OFF"
|
||||
}
|
||||
);
|
||||
|
||||
// Next we print the config file we're using, if any was defined with either -c <file> or
|
||||
// --config <file>
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg};
|
||||
|
||||
fn main() {
|
||||
|
||||
// Once all App settings (including all arguments) have been set, you call get_matches() which
|
||||
// parses the string provided by the user, and returns all the valid matches to the ones you
|
||||
// specified.
|
||||
|
@ -18,22 +17,28 @@ fn main() {
|
|||
// argument which is the input file we want to work with, this will be the only required
|
||||
// argument.
|
||||
let matches = App::new("MyApp")
|
||||
.about("Parses an input file to do awesome things")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d")
|
||||
.long("debug"))
|
||||
.arg(Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.short("c")
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true))
|
||||
.get_matches();
|
||||
.about("Parses an input file to do awesome things")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.arg(
|
||||
Arg::with_name("debug")
|
||||
.help("turn on debugging information")
|
||||
.short("d")
|
||||
.long("debug"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.help("sets the config file to use")
|
||||
.short("c")
|
||||
.long("config"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the input file to use")
|
||||
.index(1)
|
||||
.required(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// We can find out whether or not debugging was turned on
|
||||
if matches.is_present("debug") {
|
||||
|
@ -48,7 +53,10 @@ fn main() {
|
|||
|
||||
// Because "input" is required we can safely call unwrap() because had the user NOT
|
||||
// specified a value, clap would have explained the error the user, and exited.
|
||||
println!("Doing real work with file: {}", matches.value_of("input").unwrap() );
|
||||
println!(
|
||||
"Doing real work with file: {}",
|
||||
matches.value_of("input").unwrap()
|
||||
);
|
||||
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg};
|
||||
|
||||
fn main() {
|
||||
|
||||
// Of the three argument types, flags are the most simple. Flags are simple switches which can
|
||||
// be either "on" or "off"
|
||||
//
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg};
|
||||
|
||||
fn main() {
|
||||
|
||||
// Positional arguments are those values after the program name which are not preceded by any
|
||||
// identifier (such as "myapp some_file"). Positionals support many of the same options as
|
||||
// flags, as well as a few additional ones.
|
||||
|
@ -50,7 +49,11 @@ fn main() {
|
|||
// We can also get the values for those arguments
|
||||
if let Some(ref in_file) = matches.value_of("input") {
|
||||
// It's safe to call unwrap() because of the required options we set above
|
||||
println!("Doing work with {} and {}", in_file, matches.value_of("config").unwrap());
|
||||
println!(
|
||||
"Doing work with {} and {}",
|
||||
in_file,
|
||||
matches.value_of("config").unwrap()
|
||||
);
|
||||
}
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg};
|
||||
|
||||
fn main() {
|
||||
|
||||
// Option arguments are those that take an additional value, such as "-c value". In clap they
|
||||
// support three types of specification, those with short() as "-o some", or those with long()
|
||||
// as "--option value" or "--option=value"
|
||||
|
@ -65,7 +64,10 @@ fn main() {
|
|||
// NOTE: Just like with flags, if we did not specify the multiple() setting this will only
|
||||
// return 1 no matter how many times the argument was used (unless it wasn't used at all, in
|
||||
// in which case 0 is returned)
|
||||
println!("The \"input\" argument was used {} times", matches.occurrences_of("input"));
|
||||
println!(
|
||||
"The \"input\" argument was used {} times",
|
||||
matches.occurrences_of("input")
|
||||
);
|
||||
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ extern crate clap;
|
|||
use clap::{App, Arg, SubCommand};
|
||||
|
||||
fn main() {
|
||||
|
||||
// SubCommands function exactly like sub-Apps, because that's exactly what they are. Each
|
||||
// instance of a SubCommand can have it's own version, author(s), Args, and even it's own
|
||||
// subcommands.
|
||||
|
@ -49,8 +48,8 @@ fn main() {
|
|||
// You can also match on a subcommand's name
|
||||
match matches.subcommand_name() {
|
||||
Some("add") => println!("'myapp add' was used"),
|
||||
None => println!("No subcommand was used"),
|
||||
_ => println!("Some other subcommand was used"),
|
||||
None => println!("No subcommand was used"),
|
||||
_ => println!("Some other subcommand was used"),
|
||||
}
|
||||
|
||||
// Continued program logic goes here...
|
||||
|
|
|
@ -12,22 +12,25 @@ fn main() {
|
|||
//
|
||||
// For this example, assume you want one positional argument of either "fast" or "slow"
|
||||
// i.e. the only possible ways to run the program are "myprog fast" or "myprog slow"
|
||||
let matches = App::new("myapp").about("does awesome things")
|
||||
.arg(Arg::with_name("MODE")
|
||||
.help("What mode to run the program in")
|
||||
.index(1)
|
||||
.possible_values(&["fast", "slow"])
|
||||
.required(true))
|
||||
.get_matches();
|
||||
let matches = App::new("myapp")
|
||||
.about("does awesome things")
|
||||
.arg(
|
||||
Arg::with_name("MODE")
|
||||
.help("What mode to run the program in")
|
||||
.index(1)
|
||||
.possible_values(&["fast", "slow"])
|
||||
.required(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// Note, it's safe to call unwrap() because the arg is required
|
||||
match matches.value_of("MODE").unwrap() {
|
||||
"fast" => {
|
||||
// Do fast things...
|
||||
},
|
||||
}
|
||||
"slow" => {
|
||||
// Do slow things...
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,12 +55,11 @@ fn main() {
|
|||
let t = value_t!(m.value_of("foo"), Foo).unwrap_or_else(|e| e.exit());
|
||||
let t2 = value_t!(m.value_of("oof"), Oof).unwrap_or_else(|e| e.exit());
|
||||
|
||||
|
||||
// Now we can use our enum like normal.
|
||||
match t {
|
||||
Foo::Bar => println!("Found a Bar"),
|
||||
Foo::Baz => println!("Found a Baz"),
|
||||
Foo::Qux => println!("Found a Qux")
|
||||
Foo::Qux => println!("Found a Qux"),
|
||||
}
|
||||
|
||||
// Since our Oof derives Debug, we can do this:
|
||||
|
|
|
@ -15,7 +15,7 @@ enum Vals {
|
|||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
Qux
|
||||
Qux,
|
||||
}
|
||||
|
||||
// Implement the trait
|
||||
|
@ -28,7 +28,7 @@ impl FromStr for Vals {
|
|||
"Bar" => Ok(Vals::Bar),
|
||||
"Baz" => Ok(Vals::Baz),
|
||||
"Qux" => Ok(Vals::Qux),
|
||||
_ => Err("no match")
|
||||
_ => Err("no match"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,6 @@ fn main() {
|
|||
Vals::Foo => println!("Found a Foo"),
|
||||
Vals::Bar => println!("Found a Bar"),
|
||||
Vals::Baz => println!("Found a Baz"),
|
||||
Vals::Qux => println!("Found a Qux")
|
||||
Vals::Qux => println!("Found a Qux"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
/// of the three numbers. So you create three flags `--major`, `--minor`, and `--patch`. All of
|
||||
/// these arguments shouldn't be used at one time but you want to specify that *at least one* of
|
||||
/// them is used. For this, you can create a group.
|
||||
|
||||
extern crate clap;
|
||||
|
||||
use clap::{App, Arg, ArgGroup};
|
||||
|
@ -61,14 +60,16 @@ fn main() {
|
|||
format!("{}", ver)
|
||||
} else {
|
||||
// Increment the one requested (in a real program, we'd reset the lower numbers)
|
||||
let (maj, min, pat) = (matches.is_present("major"),
|
||||
matches.is_present("minor"),
|
||||
matches.is_present("patch"));
|
||||
let (maj, min, pat) = (
|
||||
matches.is_present("major"),
|
||||
matches.is_present("minor"),
|
||||
matches.is_present("patch"),
|
||||
);
|
||||
match (maj, min, pat) {
|
||||
(true, _, _) => major += 1,
|
||||
(_, true, _) => minor += 1,
|
||||
(_, _, true) => patch += 1,
|
||||
_ => unreachable!(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
format!("{}.{}.{}", major, minor, patch)
|
||||
};
|
||||
|
@ -77,11 +78,13 @@ fn main() {
|
|||
|
||||
// Check for usage of -c
|
||||
if matches.is_present("config") {
|
||||
let input = matches.value_of("INPUT_FILE").unwrap_or(matches.value_of("SPEC_IN").unwrap());
|
||||
println!("Doing work using input {} and config {}",
|
||||
input,
|
||||
matches.value_of("config").unwrap());
|
||||
let input = matches
|
||||
.value_of("INPUT_FILE")
|
||||
.unwrap_or(matches.value_of("SPEC_IN").unwrap());
|
||||
println!(
|
||||
"Doing work using input {} and config {}",
|
||||
input,
|
||||
matches.value_of("config").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,6 @@ fn main() {
|
|||
|
||||
match matches.subcommand() {
|
||||
("test", _) => println!("The 'test' subcommand was used"),
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
// [dependencies]
|
||||
// clap = { features = ["yaml"] }
|
||||
|
||||
|
||||
// Using yaml requires calling a clap macro `load_yaml!()` so we must use the '#[macro_use]'
|
||||
// directive
|
||||
#[macro_use]
|
||||
|
@ -38,7 +37,7 @@ fn main() {
|
|||
match mode {
|
||||
"vi" => println!("You are using vi"),
|
||||
"emacs" => println!("You are using emacs..."),
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else {
|
||||
println!("--mode <MODE> wasn't used...");
|
||||
|
|
|
@ -5,7 +5,6 @@ extern crate clap;
|
|||
// $crate:: internally
|
||||
|
||||
fn main() {
|
||||
|
||||
// Validation example testing that a file exists
|
||||
let file_exists = |path| {
|
||||
if std::fs::metadata(path).is_ok() {
|
||||
|
|
|
@ -41,31 +41,36 @@
|
|||
|
||||
extern crate clap;
|
||||
|
||||
use clap::{App, Arg, SubCommand, AppSettings};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
|
||||
fn main() {
|
||||
|
||||
let matches = App::new("git")
|
||||
.about("A fictional versioning CLI")
|
||||
.version("1.0")
|
||||
.author("Me")
|
||||
.subcommand(SubCommand::with_name("clone")
|
||||
.about("clones repos")
|
||||
.arg(Arg::with_name("repo")
|
||||
.help("The repo to clone")
|
||||
.required(true)))
|
||||
.subcommand(SubCommand::with_name("push")
|
||||
.about("pushes things")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(SubCommand::with_name("remote") // Subcommands can have thier own subcommands,
|
||||
.subcommand(
|
||||
SubCommand::with_name("clone").about("clones repos").arg(
|
||||
Arg::with_name("repo")
|
||||
.help("The repo to clone")
|
||||
.required(true),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("push")
|
||||
.about("pushes things")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.subcommand(
|
||||
SubCommand::with_name("remote") // Subcommands can have thier own subcommands,
|
||||
// which in turn have their own subcommands
|
||||
.about("pushes remote things")
|
||||
.arg(Arg::with_name("repo")
|
||||
.required(true)
|
||||
.help("The remote repo to push things to")))
|
||||
.subcommand(SubCommand::with_name("local")
|
||||
.about("pushes local things")))
|
||||
.subcommand(SubCommand::with_name("add")
|
||||
.help("The remote repo to push things to")),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("local").about("pushes local things")),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("add")
|
||||
.about("adds things")
|
||||
.author("Someone Else") // Subcommands can list different authors
|
||||
.version("v2.0 (I'm versioned differently") // or different version from their parents
|
||||
|
@ -74,7 +79,8 @@ fn main() {
|
|||
.long("stuff")
|
||||
.help("Stuff to add")
|
||||
.takes_value(true)
|
||||
.multiple(true)))
|
||||
.multiple(true)),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// At this point, the matches we have point to git. Keep this in mind...
|
||||
|
@ -101,8 +107,8 @@ fn main() {
|
|||
Some("clone") => println!("'git clone' was used"),
|
||||
Some("push") => println!("'git push' was used"),
|
||||
Some("add") => println!("'git add' was used"),
|
||||
None => println!("No subcommand was used"),
|
||||
_ => unreachable!(), // Assuming you've listed all direct children above, this is unreachable
|
||||
None => println!("No subcommand was used"),
|
||||
_ => unreachable!(), // Assuming you've listed all direct children above, this is unreachable
|
||||
}
|
||||
|
||||
// You could get the independent subcommand matches, although this is less common
|
||||
|
@ -114,29 +120,36 @@ fn main() {
|
|||
// The most common way to handle subcommands is via a combined approach using
|
||||
// `ArgMatches::subcommand` which returns a tuple of both the name and matches
|
||||
match matches.subcommand() {
|
||||
("clone", Some(clone_matches)) =>{
|
||||
("clone", Some(clone_matches)) => {
|
||||
// Now we have a reference to clone's matches
|
||||
println!("Cloning {}", clone_matches.value_of("repo").unwrap());
|
||||
},
|
||||
("push", Some(push_matches)) =>{
|
||||
}
|
||||
("push", Some(push_matches)) => {
|
||||
// Now we have a reference to push's matches
|
||||
match push_matches.subcommand() {
|
||||
("remote", Some(remote_matches)) =>{
|
||||
("remote", Some(remote_matches)) => {
|
||||
// Now we have a reference to remote's matches
|
||||
println!("Pushing to {}", remote_matches.value_of("repo").unwrap());
|
||||
},
|
||||
("local", Some(_)) =>{
|
||||
}
|
||||
("local", Some(_)) => {
|
||||
println!("'git push local' was used");
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
},
|
||||
("add", Some(add_matches)) =>{
|
||||
}
|
||||
("add", Some(add_matches)) => {
|
||||
// Now we have a reference to add's matches
|
||||
println!("Adding {}", add_matches.values_of("stuff").unwrap().collect::<Vec<_>>().join(", "));
|
||||
},
|
||||
("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
|
||||
_ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
|
||||
println!(
|
||||
"Adding {}",
|
||||
add_matches
|
||||
.values_of("stuff")
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
("", None) => println!("No subcommand was used"), // If no subcommand was usd it'll match the tuple ("", None)
|
||||
_ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
|
||||
}
|
||||
|
||||
// Continued program logic goes here...
|
||||
|
|
|
@ -3,19 +3,21 @@ extern crate clap;
|
|||
use clap::{App, Arg, SubCommand};
|
||||
|
||||
fn main() {
|
||||
|
||||
let matches = App::new("MyApp")
|
||||
.subcommand(SubCommand::with_name("ls")
|
||||
.aliases(&["list", "dir"])
|
||||
.about("Adds files to myapp")
|
||||
.version("0.1")
|
||||
.author("Kevin K.")
|
||||
.arg(Arg::with_name("input")
|
||||
.help("the file to add")
|
||||
.index(1)
|
||||
.required(true))
|
||||
)
|
||||
.get_matches();
|
||||
.subcommand(
|
||||
SubCommand::with_name("ls")
|
||||
.aliases(&["list", "dir"])
|
||||
.about("Adds files to myapp")
|
||||
.version("0.1")
|
||||
.author("Kevin K.")
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.help("the file to add")
|
||||
.index(1)
|
||||
.required(true),
|
||||
),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
// You can check if a subcommand was used like normal
|
||||
if matches.is_present("add") {
|
||||
|
@ -31,8 +33,8 @@ fn main() {
|
|||
// You can also match on a subcommand's name
|
||||
match matches.subcommand_name() {
|
||||
Some("add") => println!("'myapp add' was used"),
|
||||
None => println!("No subcommand was used"),
|
||||
_ => println!("Some other subcommand was used"),
|
||||
None => println!("No subcommand was used"),
|
||||
_ => println!("Some other subcommand was used"),
|
||||
}
|
||||
|
||||
// Continued program logic goes here...
|
||||
|
|
|
@ -4,22 +4,20 @@ use clap::{App, Arg};
|
|||
|
||||
/// myprog -f -p=bob -- sloppy slop slop
|
||||
fn main() {
|
||||
|
||||
let matches = App::new("myprog")
|
||||
.arg(Arg::with_name("eff")
|
||||
.short("f"))
|
||||
.arg(Arg::with_name("pea")
|
||||
.short("p")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("slop")
|
||||
.multiple(true)
|
||||
.last(true))
|
||||
.arg(Arg::with_name("eff").short("f"))
|
||||
.arg(Arg::with_name("pea").short("p").takes_value(true))
|
||||
.arg(Arg::with_name("slop").multiple(true).last(true))
|
||||
.get_matches();
|
||||
|
||||
|
||||
println!("-f used: {:?}", matches.is_present("eff"));
|
||||
println!("-p's value: {:?}", matches.value_of("pea"));
|
||||
println!("'slops' values: {:?}", matches.values_of("slop").map(|vals| vals.collect::<Vec<_>>()));
|
||||
println!(
|
||||
"'slops' values: {:?}",
|
||||
matches
|
||||
.values_of("slop")
|
||||
.map(|vals| vals.collect::<Vec<_>>())
|
||||
);
|
||||
|
||||
// Continued program logic goes here...
|
||||
}
|
||||
|
|
30
justfile
30
justfile
|
@ -1,3 +1,4 @@
|
|||
|
||||
@update-contributors:
|
||||
echo 'Removing old CONTRIBUTORS.md'
|
||||
mv CONTRIBUTORS.md CONTRIBUTORS.md.bak
|
||||
|
@ -11,11 +12,11 @@
|
|||
echo "This list was generated by [mgechev/github-contributors-list](https://github.com/mgechev/github-contributors-list)" >> CONTRIBUTORS.md
|
||||
rm CONTRIBUTORS.md.bak
|
||||
|
||||
run-test TEST:
|
||||
cargo test --test {{TEST}}
|
||||
run-test TESTG TEST="":
|
||||
cargo test --test {{TESTG}} -- {{TEST}}
|
||||
|
||||
debug TEST:
|
||||
cargo test --test {{TEST}} --features debug
|
||||
debug TESTG TEST="":
|
||||
cargo test --test {{TESTG}} --features debug -- {{TEST}}
|
||||
|
||||
run-tests:
|
||||
cargo test --features "yaml unstable"
|
||||
|
@ -37,3 +38,24 @@ clean:
|
|||
find . -type f -name "*.orig" -exec rm {} \;
|
||||
find . -type f -name "*.bk" -exec rm {} \;
|
||||
find . -type f -name ".*~" -exec rm {} \;
|
||||
|
||||
top-errors NUM="95":
|
||||
@cargo check 2>&1 | head -n {{NUM}}
|
||||
|
||||
count-errors:
|
||||
@cargo check 2>&1 | grep -e '^error' | wc -l
|
||||
|
||||
find-errors:
|
||||
@cargo check 2>&1 | grep --only-matching -e '-->[^:]*' | sort | uniq -c | sort -nr
|
||||
|
||||
count-warnings:
|
||||
@cargo check 2>&1 | grep -e '^warning' | wc -l
|
||||
|
||||
find-warnings:
|
||||
@cargo check 2>&1 | grep -A1 -e 'warning' | grep --only-matching -e '-->[^:]*' | sort | uniq -c | sort -nr
|
||||
|
||||
@update-todo:
|
||||
./etc/update-todo.sh
|
||||
|
||||
@count-failures:
|
||||
./etc/count-tests.sh
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
format_strings = false
|
||||
chain_overflow_last = false
|
||||
same_line_if_else = true
|
||||
fn_single_line = true
|
||||
|
|
403
src/app/help.rs
403
src/app/help.rs
|
@ -2,17 +2,16 @@
|
|||
use std::borrow::Cow;
|
||||
use std::cmp;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt::Display;
|
||||
use std::io::{self, Cursor, Read, Write};
|
||||
use std::usize;
|
||||
|
||||
// Internal
|
||||
use app::{App, AppSettings};
|
||||
use app::parser::Parser;
|
||||
use args::{AnyArg, ArgSettings, DispOrder};
|
||||
use args::{Arg, ArgSettings};
|
||||
use errors::{Error, Result as ClapResult};
|
||||
use fmt::{Colorizer, ColorizerOption, Format};
|
||||
use app::usage;
|
||||
use app::usage::Usage;
|
||||
use map::VecMap;
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
|
@ -31,29 +30,16 @@ fn str_width(s: &str) -> usize { UnicodeWidthStr::width(s) }
|
|||
|
||||
const TAB: &'static str = " ";
|
||||
|
||||
// These are just convenient traits to make the code easier to read.
|
||||
trait ArgWithDisplay<'b, 'c>: AnyArg<'b, 'c> + Display {}
|
||||
impl<'b, 'c, T> ArgWithDisplay<'b, 'c> for T
|
||||
where
|
||||
T: AnyArg<'b, 'c> + Display,
|
||||
{
|
||||
}
|
||||
|
||||
trait ArgWithOrder<'b, 'c>: ArgWithDisplay<'b, 'c> + DispOrder {
|
||||
fn as_base(&self) -> &ArgWithDisplay<'b, 'c>;
|
||||
}
|
||||
impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T
|
||||
where
|
||||
T: ArgWithDisplay<'b, 'c> + DispOrder,
|
||||
{
|
||||
fn as_base(&self) -> &ArgWithDisplay<'b, 'c> { self }
|
||||
}
|
||||
|
||||
fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> { x }
|
||||
|
||||
impl<'b, 'c> DispOrder for App<'b, 'c> {
|
||||
fn disp_ord(&self) -> usize { 999 }
|
||||
}
|
||||
// trait ArgWithOrder<'b, 'c>: Display + DispOrder {
|
||||
// fn as_base(&self) -> &Arg<'b, 'c>;
|
||||
// }
|
||||
// impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T
|
||||
// where
|
||||
// T: Display + DispOrder,
|
||||
// {
|
||||
// fn as_base(&self) -> &Arg<'b, 'c> { self }
|
||||
// }
|
||||
// fn as_arg_trait<'w, 'b, T: ArgWithOrder<'w, 'b>>(x: &T) -> &ArgWithOrder<'w, 'b> { x }
|
||||
|
||||
macro_rules! color {
|
||||
($_self:ident, $s:expr, $c:ident) => {
|
||||
|
@ -75,8 +61,8 @@ macro_rules! color {
|
|||
/// `clap` Help Writer.
|
||||
///
|
||||
/// Wraps a writer stream providing different methods to generate help for `clap` objects.
|
||||
pub struct Help<'a> {
|
||||
writer: &'a mut Write,
|
||||
pub struct Help<'w> {
|
||||
writer: &'w mut Write,
|
||||
next_line_help: bool,
|
||||
hide_pv: bool,
|
||||
term_w: usize,
|
||||
|
@ -88,11 +74,11 @@ pub struct Help<'a> {
|
|||
}
|
||||
|
||||
// Public Functions
|
||||
impl<'a> Help<'a> {
|
||||
impl<'w> Help<'w> {
|
||||
/// Create a new `Help` instance.
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
||||
pub fn new(
|
||||
w: &'a mut Write,
|
||||
w: &'w mut Write,
|
||||
next_line_help: bool,
|
||||
hide_pv: bool,
|
||||
color: bool,
|
||||
|
@ -128,16 +114,9 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Reads help settings from an App
|
||||
/// and write its help to the wrapped stream.
|
||||
pub fn write_app_help(w: &'a mut Write, app: &App, use_long: bool) -> ClapResult<()> {
|
||||
debugln!("Help::write_app_help;");
|
||||
Self::write_parser_help(w, &app.p, use_long)
|
||||
}
|
||||
|
||||
/// Reads help settings from a Parser
|
||||
/// and write its help to the wrapped stream.
|
||||
pub fn write_parser_help(w: &'a mut Write, parser: &Parser, use_long: bool) -> ClapResult<()> {
|
||||
pub fn write_parser_help(w: &'w mut Write, parser: &Parser, use_long: bool) -> ClapResult<()> {
|
||||
debugln!("Help::write_parser_help;");
|
||||
Self::_write_parser_help(w, parser, false, use_long)
|
||||
}
|
||||
|
@ -145,14 +124,14 @@ impl<'a> Help<'a> {
|
|||
/// Reads help settings from a Parser
|
||||
/// and write its help to the wrapped stream which will be stderr. This method prevents
|
||||
/// formatting when required.
|
||||
pub fn write_parser_help_to_stderr(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
|
||||
pub fn write_parser_help_to_stderr(w: &'w mut Write, parser: &Parser) -> ClapResult<()> {
|
||||
debugln!("Help::write_parser_help;");
|
||||
Self::_write_parser_help(w, parser, true, false)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _write_parser_help(
|
||||
w: &'a mut Write,
|
||||
w: &'w mut Write,
|
||||
parser: &Parser,
|
||||
stderr: bool,
|
||||
use_long: bool,
|
||||
|
@ -163,7 +142,7 @@ impl<'a> Help<'a> {
|
|||
let color = parser.is_set(AppSettings::ColoredHelp);
|
||||
let cizer = Colorizer::new(ColorizerOption {
|
||||
use_stderr: stderr,
|
||||
when: parser.color(),
|
||||
when: parser.app.color(),
|
||||
});
|
||||
Self::new(
|
||||
w,
|
||||
|
@ -171,8 +150,8 @@ impl<'a> Help<'a> {
|
|||
hide_v,
|
||||
color,
|
||||
cizer,
|
||||
parser.meta.term_w,
|
||||
parser.meta.max_w,
|
||||
parser.app.term_w,
|
||||
parser.app.max_w,
|
||||
use_long,
|
||||
).write_help(parser)
|
||||
}
|
||||
|
@ -180,9 +159,9 @@ impl<'a> Help<'a> {
|
|||
/// Writes the parser help to the wrapped stream.
|
||||
pub fn write_help(&mut self, parser: &Parser) -> ClapResult<()> {
|
||||
debugln!("Help::write_help;");
|
||||
if let Some(h) = parser.meta.help_str {
|
||||
if let Some(h) = parser.app.help_str {
|
||||
write!(self.writer, "{}", h).map_err(Error::from)?;
|
||||
} else if let Some(tmpl) = parser.meta.template {
|
||||
} else if let Some(tmpl) = parser.app.template {
|
||||
self.write_templated_help(parser, tmpl)?;
|
||||
} else {
|
||||
self.write_default_help(parser)?;
|
||||
|
@ -191,12 +170,13 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Methods to write AnyArg help.
|
||||
impl<'a> Help<'a> {
|
||||
// Methods to write Arg help.
|
||||
impl<'w> Help<'w> {
|
||||
/// Writes help for each argument in the order they were declared to the wrapped stream.
|
||||
fn write_args_unsorted<'b: 'd, 'c: 'd, 'd, I: 'd>(&mut self, args: I) -> io::Result<()>
|
||||
fn write_args_unsorted<'a, 'b, I>(&mut self, args: I) -> io::Result<()>
|
||||
where
|
||||
I: Iterator<Item = &'d ArgWithOrder<'b, 'c>>,
|
||||
'a: 'b,
|
||||
I: Iterator<Item = &'b Arg<'a, 'b>>,
|
||||
{
|
||||
debugln!("Help::write_args_unsorted;");
|
||||
// The shortest an arg can legally be is 2 (i.e. '-x')
|
||||
|
@ -217,15 +197,16 @@ impl<'a> Help<'a> {
|
|||
} else {
|
||||
self.writer.write_all(b"\n")?;
|
||||
}
|
||||
self.write_arg(arg.as_base())?;
|
||||
self.write_arg(arg)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Sorts arguments by length and display order and write their help to the wrapped stream.
|
||||
fn write_args<'b: 'd, 'c: 'd, 'd, I: 'd>(&mut self, args: I) -> io::Result<()>
|
||||
fn write_args<'a, 'b, I>(&mut self, args: I) -> io::Result<()>
|
||||
where
|
||||
I: Iterator<Item = &'d ArgWithOrder<'b, 'c>>,
|
||||
'a: 'b,
|
||||
I: Iterator<Item = &'b Arg<'a, 'b>>,
|
||||
{
|
||||
debugln!("Help::write_args;");
|
||||
// The shortest an arg can legally be is 2 (i.e. '-x')
|
||||
|
@ -233,8 +214,8 @@ impl<'a> Help<'a> {
|
|||
let mut ord_m = VecMap::new();
|
||||
// Determine the longest
|
||||
for arg in args.filter(|arg| {
|
||||
// If it's NextLineHelp, but we don't care to compute how long because it may be
|
||||
// NextLineHelp on purpose *because* it's so long and would throw off all other
|
||||
// If it's NextLineHelp we don't care to compute how long it is because it may be
|
||||
// NextLineHelp on purpose simply *because* it's so long and would throw off all other
|
||||
// args alignment
|
||||
!arg.is_set(ArgSettings::Hidden) || arg.is_set(ArgSettings::NextLineHelp)
|
||||
}) {
|
||||
|
@ -243,8 +224,8 @@ impl<'a> Help<'a> {
|
|||
self.longest = cmp::max(self.longest, str_width(arg.to_string().as_str()));
|
||||
debugln!("Help::write_args: New Longest...{}", self.longest);
|
||||
}
|
||||
let btm = ord_m.entry(arg.disp_ord()).or_insert(BTreeMap::new());
|
||||
btm.insert(arg.name(), arg);
|
||||
let btm = ord_m.entry(arg.disp_ord).or_insert(BTreeMap::new());
|
||||
btm.insert(arg.name, arg);
|
||||
}
|
||||
let mut first = true;
|
||||
for btm in ord_m.values() {
|
||||
|
@ -254,14 +235,14 @@ impl<'a> Help<'a> {
|
|||
} else {
|
||||
self.writer.write_all(b"\n")?;
|
||||
}
|
||||
self.write_arg(arg.as_base())?;
|
||||
self.write_arg(arg)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes help for an argument to the wrapped stream.
|
||||
fn write_arg<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>) -> io::Result<()> {
|
||||
fn write_arg<'b, 'c>(&mut self, arg: &Arg<'b, 'c>) -> io::Result<()> {
|
||||
debugln!("Help::write_arg;");
|
||||
self.short(arg)?;
|
||||
self.long(arg)?;
|
||||
|
@ -271,10 +252,10 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
/// Writes argument's short command to the wrapped stream.
|
||||
fn short<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>) -> io::Result<()> {
|
||||
fn short<'b, 'c>(&mut self, arg: &Arg<'b, 'c>) -> io::Result<()> {
|
||||
debugln!("Help::short;");
|
||||
write!(self.writer, "{}", TAB)?;
|
||||
if let Some(s) = arg.short() {
|
||||
if let Some(s) = arg.short {
|
||||
color!(self, "-{}", s, good)
|
||||
} else if arg.has_switch() {
|
||||
write!(self.writer, "{}", TAB)
|
||||
|
@ -284,14 +265,14 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
/// Writes argument's long command to the wrapped stream.
|
||||
fn long<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>) -> io::Result<()> {
|
||||
fn long<'b, 'c>(&mut self, arg: &Arg<'b, 'c>) -> io::Result<()> {
|
||||
debugln!("Help::long;");
|
||||
if !arg.has_switch() {
|
||||
return Ok(());
|
||||
}
|
||||
if arg.takes_value() {
|
||||
if let Some(l) = arg.long() {
|
||||
if arg.short().is_some() {
|
||||
if arg.is_set(ArgSettings::TakesValue) {
|
||||
if let Some(l) = arg.long {
|
||||
if arg.short.is_some() {
|
||||
write!(self.writer, ", ")?;
|
||||
}
|
||||
color!(self, "--{}", l, good)?
|
||||
|
@ -303,8 +284,8 @@ impl<'a> Help<'a> {
|
|||
" "
|
||||
};
|
||||
write!(self.writer, "{}", sep)?;
|
||||
} else if let Some(l) = arg.long() {
|
||||
if arg.short().is_some() {
|
||||
} else if let Some(l) = arg.long {
|
||||
if arg.short.is_some() {
|
||||
write!(self.writer, ", ")?;
|
||||
}
|
||||
color!(self, "--{}", l, good)?;
|
||||
|
@ -313,15 +294,15 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
/// Writes argument's possible values to the wrapped stream.
|
||||
fn val<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>) -> Result<String, io::Error> {
|
||||
debugln!("Help::val: arg={}", arg);
|
||||
if arg.takes_value() {
|
||||
fn val<'b, 'c>(&mut self, arg: &Arg<'b, 'c>) -> Result<String, io::Error> {
|
||||
debugln!("Help::val: arg={}", arg.name);
|
||||
if arg.is_set(ArgSettings::TakesValue) {
|
||||
let delim = if arg.is_set(ArgSettings::RequireDelimiter) {
|
||||
arg.val_delim().expect(INTERNAL_ERROR_MSG)
|
||||
arg.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
};
|
||||
if let Some(vec) = arg.val_names() {
|
||||
if let Some(ref vec) = arg.val_names {
|
||||
let mut it = vec.iter().peekable();
|
||||
while let Some((_, val)) = it.next() {
|
||||
color!(self, "<{}>", val, good)?;
|
||||
|
@ -333,10 +314,10 @@ impl<'a> Help<'a> {
|
|||
if arg.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
color!(self, "...", good)?;
|
||||
}
|
||||
} else if let Some(num) = arg.num_vals() {
|
||||
} else if let Some(num) = arg.num_vals {
|
||||
let mut it = (0..num).peekable();
|
||||
while let Some(_) = it.next() {
|
||||
color!(self, "<{}>", arg.name(), good)?;
|
||||
color!(self, "<{}>", arg.name, good)?;
|
||||
if it.peek().is_some() {
|
||||
write!(self.writer, "{}", delim)?;
|
||||
}
|
||||
|
@ -345,7 +326,7 @@ impl<'a> Help<'a> {
|
|||
color!(self, "...", good)?;
|
||||
}
|
||||
} else if arg.has_switch() {
|
||||
color!(self, "<{}>", arg.name(), good)?;
|
||||
color!(self, "<{}>", arg.name, good)?;
|
||||
if arg.is_set(ArgSettings::Multiple) {
|
||||
color!(self, "...", good)?;
|
||||
}
|
||||
|
@ -355,7 +336,7 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
let spec_vals = self.spec_vals(arg);
|
||||
let h = arg.help().unwrap_or("");
|
||||
let h = arg.help.unwrap_or("");
|
||||
let h_w = str_width(h) + str_width(&*spec_vals);
|
||||
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp);
|
||||
let taken = self.longest + 12;
|
||||
|
@ -384,7 +365,7 @@ impl<'a> Help<'a> {
|
|||
let mut spcs = self.longest - self_len;
|
||||
// Since we're writing spaces from the tab point we first need to know if we
|
||||
// had a long and short, or just short
|
||||
if arg.long().is_some() {
|
||||
if arg.long.is_some() {
|
||||
// Only account 4 after the val
|
||||
spcs += 4;
|
||||
} else {
|
||||
|
@ -440,12 +421,12 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
/// Writes argument's help to the wrapped stream.
|
||||
fn help<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>, spec_vals: &str) -> io::Result<()> {
|
||||
fn help<'b, 'c>(&mut self, arg: &Arg<'b, 'c>, spec_vals: &str) -> io::Result<()> {
|
||||
debugln!("Help::help;");
|
||||
let h = if self.use_long {
|
||||
arg.long_help().unwrap_or_else(|| arg.help().unwrap_or(""))
|
||||
arg.long_help.unwrap_or_else(|| arg.help.unwrap_or(""))
|
||||
} else {
|
||||
arg.help().unwrap_or_else(|| arg.long_help().unwrap_or(""))
|
||||
arg.help.unwrap_or_else(|| arg.long_help.unwrap_or(""))
|
||||
};
|
||||
let mut help = String::from(h) + spec_vals;
|
||||
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long;
|
||||
|
@ -496,29 +477,30 @@ impl<'a> Help<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn spec_vals(&self, a: &ArgWithDisplay) -> String {
|
||||
fn spec_vals(&self, a: &Arg) -> String {
|
||||
debugln!("Help::spec_vals: a={}", a);
|
||||
let mut spec_vals = vec![];
|
||||
if let Some(ref env) = a.env() {
|
||||
if let Some(ref env) = a.env {
|
||||
debugln!(
|
||||
"Help::spec_vals: Found environment variable...[{:?}:{:?}]",
|
||||
env.0,
|
||||
env.1
|
||||
);
|
||||
let env_val = if !a.is_set(ArgSettings::HideEnvValues) {
|
||||
format!("={}", env.1.map_or(Cow::Borrowed(""), |val| val.to_string_lossy()))
|
||||
format!(
|
||||
"={}",
|
||||
env.1
|
||||
.as_ref()
|
||||
.map_or(Cow::Borrowed(""), |val| val.to_string_lossy())
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let env_info = format!(
|
||||
" [env: {}{}]",
|
||||
env.0.to_string_lossy(),
|
||||
env_val
|
||||
);
|
||||
let env_info = format!(" [env: {}{}]", env.0.to_string_lossy(), env_val);
|
||||
spec_vals.push(env_info);
|
||||
}
|
||||
if !a.is_set(ArgSettings::HideDefaultValue) {
|
||||
if let Some(pv) = a.default_val() {
|
||||
if let Some(pv) = a.default_val {
|
||||
debugln!("Help::spec_vals: Found default value...[{:?}]", pv);
|
||||
spec_vals.push(format!(
|
||||
" [default: {}]",
|
||||
|
@ -530,23 +512,29 @@ impl<'a> Help<'a> {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(ref aliases) = a.aliases() {
|
||||
if let Some(ref aliases) = a.aliases {
|
||||
debugln!("Help::spec_vals: Found aliases...{:?}", aliases);
|
||||
spec_vals.push(format!(
|
||||
" [aliases: {}]",
|
||||
if self.color {
|
||||
aliases
|
||||
.iter()
|
||||
.map(|v| format!("{}", self.cizer.good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
} else {
|
||||
aliases.join(", ")
|
||||
}
|
||||
));
|
||||
let als = if self.color {
|
||||
aliases
|
||||
.iter()
|
||||
.filter(|&als| als.1) // visible
|
||||
.map(|&als| format!("{}", self.cizer.good(als.0))) // name
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
} else {
|
||||
aliases
|
||||
.iter()
|
||||
.filter(|&als| als.1)
|
||||
.map(|&als| als.0)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
};
|
||||
if !als.is_empty() {
|
||||
spec_vals.push(format!(" [aliases: {}]", als));
|
||||
}
|
||||
}
|
||||
if !self.hide_pv && !a.is_set(ArgSettings::HidePossibleValues) {
|
||||
if let Some(pv) = a.possible_vals() {
|
||||
if let Some(ref pv) = a.possible_vals {
|
||||
debugln!("Help::spec_vals: Found possible vals...{:?}", pv);
|
||||
spec_vals.push(if self.color {
|
||||
format!(
|
||||
|
@ -565,9 +553,121 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Methods to write a single subcommand
|
||||
impl<'w> Help<'w> {
|
||||
fn write_subcommand<'a, 'b>(&mut self, app: &App<'a, 'b>) -> io::Result<()> {
|
||||
debugln!("Help::write_subcommand;");
|
||||
write!(self.writer, "{}", TAB)?;
|
||||
color!(self, "{}", app.name, good)?;
|
||||
let spec_vals = self.sc_val(app)?;
|
||||
self.sc_help(app, &*spec_vals)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sc_val<'a, 'b>(&mut self, app: &App<'a, 'b>) -> Result<String, io::Error> {
|
||||
debugln!("Help::sc_val: app={}", app.name);
|
||||
let spec_vals = self.sc_spec_vals(app);
|
||||
let h = app.about.unwrap_or("");
|
||||
let h_w = str_width(h) + str_width(&*spec_vals);
|
||||
let nlh = self.next_line_help;
|
||||
let taken = self.longest + 12;
|
||||
self.force_next_line = !nlh && self.term_w >= taken
|
||||
&& (taken as f32 / self.term_w as f32) > 0.40
|
||||
&& h_w > (self.term_w - taken);
|
||||
|
||||
if !(nlh || self.force_next_line) {
|
||||
write_nspaces!(
|
||||
self.writer,
|
||||
self.longest + 4 - (str_width(app.to_string().as_str()))
|
||||
);
|
||||
}
|
||||
Ok(spec_vals)
|
||||
}
|
||||
|
||||
fn sc_spec_vals(&self, a: &App) -> String {
|
||||
debugln!("Help::sc_spec_vals: a={}", a.name);
|
||||
let mut spec_vals = vec![];
|
||||
if let Some(ref aliases) = a.aliases {
|
||||
debugln!("Help::spec_vals: Found aliases...{:?}", aliases);
|
||||
let als = if self.color {
|
||||
aliases
|
||||
.iter()
|
||||
.filter(|&als| als.1) // visible
|
||||
.map(|&als| format!("{}", self.cizer.good(als.0))) // name
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
} else {
|
||||
aliases
|
||||
.iter()
|
||||
.filter(|&als| als.1)
|
||||
.map(|&als| als.0)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
};
|
||||
if !als.is_empty() {
|
||||
spec_vals.push(format!(" [aliases: {}]", als));
|
||||
}
|
||||
}
|
||||
spec_vals.join(" ")
|
||||
}
|
||||
|
||||
fn sc_help<'a, 'b>(&mut self, app: &App<'a, 'b>, spec_vals: &str) -> io::Result<()> {
|
||||
debugln!("Help::sc_help;");
|
||||
let h = if self.use_long {
|
||||
app.long_about.unwrap_or_else(|| app.about.unwrap_or(""))
|
||||
} else {
|
||||
app.about.unwrap_or_else(|| app.long_about.unwrap_or(""))
|
||||
};
|
||||
let mut help = String::from(h) + spec_vals;
|
||||
let nlh = self.next_line_help || self.use_long;
|
||||
debugln!("Help::sc_help: Next Line...{:?}", nlh);
|
||||
|
||||
let spcs = if nlh || self.force_next_line {
|
||||
12 // "tab" * 3
|
||||
} else {
|
||||
self.longest + 12
|
||||
};
|
||||
|
||||
let too_long = spcs + str_width(h) + str_width(&*spec_vals) >= self.term_w;
|
||||
|
||||
// Is help on next line, if so then indent
|
||||
if nlh || self.force_next_line {
|
||||
write!(self.writer, "\n{}{}{}", TAB, TAB, TAB)?;
|
||||
}
|
||||
|
||||
debug!("Help::sc_help: Too long...");
|
||||
if too_long && spcs <= self.term_w || h.contains("{n}") {
|
||||
sdebugln!("Yes");
|
||||
debugln!("Help::sc_help: help...{}", help);
|
||||
debugln!("Help::sc_help: help width...{}", str_width(&*help));
|
||||
// Determine how many newlines we need to insert
|
||||
let avail_chars = self.term_w - spcs;
|
||||
debugln!("Help::sc_help: Usable space...{}", avail_chars);
|
||||
help = wrap_help(&help.replace("{n}", "\n"), avail_chars);
|
||||
} else {
|
||||
sdebugln!("No");
|
||||
}
|
||||
if let Some(part) = help.lines().next() {
|
||||
write!(self.writer, "{}", part)?;
|
||||
}
|
||||
for part in help.lines().skip(1) {
|
||||
write!(self.writer, "\n")?;
|
||||
if nlh || self.force_next_line {
|
||||
write!(self.writer, "{}{}{}", TAB, TAB, TAB)?;
|
||||
} else {
|
||||
write_nspaces!(self.writer, self.longest + 8);
|
||||
}
|
||||
write!(self.writer, "{}", part)?;
|
||||
}
|
||||
if !help.contains('\n') && (nlh || self.force_next_line) {
|
||||
write!(self.writer, "\n")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Methods to write Parser help.
|
||||
impl<'a> Help<'a> {
|
||||
impl<'w> Help<'w> {
|
||||
/// Writes help for all arguments (options, flags, args, subcommands)
|
||||
/// including titles of a Parser Object to the wrapped stream.
|
||||
#[cfg_attr(feature = "lints", allow(useless_let_if_seq))]
|
||||
|
@ -575,10 +675,14 @@ impl<'a> Help<'a> {
|
|||
pub fn write_all_args(&mut self, parser: &Parser) -> ClapResult<()> {
|
||||
debugln!("Help::write_all_args;");
|
||||
let flags = parser.has_flags();
|
||||
let pos = parser
|
||||
.positionals()
|
||||
.filter(|arg| !arg.is_set(ArgSettings::Hidden))
|
||||
.count() > 0;
|
||||
// Strange filter/count vs fold... https://github.com/rust-lang/rust/issues/33038
|
||||
let pos = positionals!(parser.app).fold(0, |acc, arg| {
|
||||
if arg.is_set(ArgSettings::Hidden) {
|
||||
acc
|
||||
} else {
|
||||
acc + 1
|
||||
}
|
||||
}) > 0;
|
||||
let opts = parser.has_opts();
|
||||
let subcmds = parser.has_visible_subcommands();
|
||||
|
||||
|
@ -587,17 +691,14 @@ impl<'a> Help<'a> {
|
|||
let mut first = true;
|
||||
|
||||
if unified_help && (flags || opts) {
|
||||
let opts_flags = parser
|
||||
.flags()
|
||||
.map(as_arg_trait)
|
||||
.chain(parser.opts().map(as_arg_trait));
|
||||
let opts_flags = args!(parser.app).filter(|a| a.has_switch());
|
||||
color!(self, "OPTIONS:\n", warning)?;
|
||||
self.write_args(opts_flags)?;
|
||||
first = false;
|
||||
} else {
|
||||
if flags {
|
||||
color!(self, "FLAGS:\n", warning)?;
|
||||
self.write_args(parser.flags().map(as_arg_trait))?;
|
||||
self.write_args(flags!(parser.app))?;
|
||||
first = false;
|
||||
}
|
||||
if opts {
|
||||
|
@ -605,7 +706,7 @@ impl<'a> Help<'a> {
|
|||
self.writer.write_all(b"\n\n")?;
|
||||
}
|
||||
color!(self, "OPTIONS:\n", warning)?;
|
||||
self.write_args(parser.opts().map(as_arg_trait))?;
|
||||
self.write_args(opts!(parser.app))?;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
@ -615,7 +716,7 @@ impl<'a> Help<'a> {
|
|||
self.writer.write_all(b"\n\n")?;
|
||||
}
|
||||
color!(self, "ARGS:\n", warning)?;
|
||||
self.write_args_unsorted(parser.positionals().map(as_arg_trait))?;
|
||||
self.write_args_unsorted(positionals!(parser.app))?;
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
@ -624,27 +725,23 @@ impl<'a> Help<'a> {
|
|||
self.writer.write_all(b"\n\n")?;
|
||||
}
|
||||
color!(self, "SUBCOMMANDS:\n", warning)?;
|
||||
self.write_subcommands(parser)?;
|
||||
self.write_subcommands(&parser.app)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes help for subcommands of a Parser Object to the wrapped stream.
|
||||
fn write_subcommands(&mut self, parser: &Parser) -> io::Result<()> {
|
||||
fn write_subcommands(&mut self, app: &App) -> io::Result<()> {
|
||||
debugln!("Help::write_subcommands;");
|
||||
// The shortest an arg can legally be is 2 (i.e. '-x')
|
||||
self.longest = 2;
|
||||
let mut ord_m = VecMap::new();
|
||||
for sc in parser
|
||||
.subcommands
|
||||
.iter()
|
||||
.filter(|s| !s.p.is_set(AppSettings::Hidden))
|
||||
{
|
||||
let btm = ord_m.entry(sc.p.meta.disp_ord).or_insert(BTreeMap::new());
|
||||
self.longest = cmp::max(self.longest, str_width(sc.p.meta.name.as_str()));
|
||||
for sc in subcommands!(app).filter(|s| !s.is_set(AppSettings::Hidden)) {
|
||||
let btm = ord_m.entry(sc.disp_ord).or_insert(BTreeMap::new());
|
||||
self.longest = cmp::max(self.longest, str_width(sc.name.as_str()));
|
||||
//self.longest = cmp::max(self.longest, sc.p.meta.name.len());
|
||||
btm.insert(sc.p.meta.name.clone(), sc.clone());
|
||||
btm.insert(sc.name.clone(), sc.clone());
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
|
@ -655,7 +752,7 @@ impl<'a> Help<'a> {
|
|||
} else {
|
||||
self.writer.write_all(b"\n")?;
|
||||
}
|
||||
self.write_arg(sc)?;
|
||||
self.write_subcommand(sc)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -664,7 +761,7 @@ impl<'a> Help<'a> {
|
|||
/// Writes version of a Parser Object to the wrapped stream.
|
||||
fn write_version(&mut self, parser: &Parser) -> io::Result<()> {
|
||||
debugln!("Help::write_version;");
|
||||
write!(self.writer, "{}", parser.meta.version.unwrap_or(""))?;
|
||||
write!(self.writer, "{}", parser.app.version.unwrap_or(""))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -673,12 +770,12 @@ impl<'a> Help<'a> {
|
|||
debugln!("Help::write_bin_name;");
|
||||
macro_rules! write_name {
|
||||
() => {{
|
||||
let mut name = parser.meta.name.clone();
|
||||
let mut name = parser.app.name.clone();
|
||||
name = name.replace("{n}", "\n");
|
||||
color!(self, wrap_help(&name, self.term_w), good)?;
|
||||
}};
|
||||
}
|
||||
if let Some(bn) = parser.meta.bin_name.as_ref() {
|
||||
if let Some(bn) = parser.app.bin_name.as_ref() {
|
||||
if bn.contains(' ') {
|
||||
// Incase we're dealing with subcommands i.e. git mv is translated to git-mv
|
||||
color!(self, bn.replace(" ", "-"), good)?
|
||||
|
@ -694,7 +791,7 @@ impl<'a> Help<'a> {
|
|||
/// Writes default help for a Parser Object to the wrapped stream.
|
||||
pub fn write_default_help(&mut self, parser: &Parser) -> ClapResult<()> {
|
||||
debugln!("Help::write_default_help;");
|
||||
if let Some(h) = parser.meta.pre_help {
|
||||
if let Some(h) = parser.app.pre_help {
|
||||
self.write_before_after_help(h)?;
|
||||
self.writer.write_all(b"\n\n")?;
|
||||
}
|
||||
|
@ -712,21 +809,21 @@ impl<'a> Help<'a> {
|
|||
self.writer.write_all(b" ")?;
|
||||
self.write_version(parser)?;
|
||||
self.writer.write_all(b"\n")?;
|
||||
if let Some(author) = parser.meta.author {
|
||||
if let Some(author) = parser.app.author {
|
||||
write_thing!(author)
|
||||
}
|
||||
if self.use_long {
|
||||
if let Some(about) = parser.meta.long_about {
|
||||
if let Some(about) = parser.app.long_about {
|
||||
debugln!("Help::write_default_help: writing long about");
|
||||
write_thing!(about)
|
||||
} else if let Some(about) = parser.meta.about {
|
||||
} else if let Some(about) = parser.app.about {
|
||||
debugln!("Help::write_default_help: writing about");
|
||||
write_thing!(about)
|
||||
}
|
||||
} else if let Some(about) = parser.meta.about {
|
||||
} else if let Some(about) = parser.app.about {
|
||||
debugln!("Help::write_default_help: writing about");
|
||||
write_thing!(about)
|
||||
} else if let Some(about) = parser.meta.long_about {
|
||||
} else if let Some(about) = parser.app.long_about {
|
||||
debugln!("Help::write_default_help: writing long about");
|
||||
write_thing!(about)
|
||||
}
|
||||
|
@ -736,7 +833,7 @@ impl<'a> Help<'a> {
|
|||
self.writer,
|
||||
"\n{}{}\n\n",
|
||||
TAB,
|
||||
usage::create_usage_no_title(parser, &[])
|
||||
Usage::new(parser).create_usage_no_title(&[])
|
||||
)?;
|
||||
|
||||
let flags = parser.has_flags();
|
||||
|
@ -748,7 +845,7 @@ impl<'a> Help<'a> {
|
|||
self.write_all_args(parser)?;
|
||||
}
|
||||
|
||||
if let Some(h) = parser.meta.more_help {
|
||||
if let Some(h) = parser.app.more_help {
|
||||
if flags || opts || pos || subcmds {
|
||||
self.writer.write_all(b"\n\n")?;
|
||||
}
|
||||
|
@ -856,9 +953,8 @@ fn copy_and_capture<R: Read, W: Write>(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Methods to write Parser help using templates.
|
||||
impl<'a> Help<'a> {
|
||||
impl<'w> Help<'w> {
|
||||
/// Write help to stream for the parser in the format defined by the template.
|
||||
///
|
||||
/// Tags arg given inside curly brackets:
|
||||
|
@ -917,67 +1013,68 @@ impl<'a> Help<'a> {
|
|||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.version.unwrap_or("unknown version")
|
||||
parser.app.version.unwrap_or("unknown version")
|
||||
)?;
|
||||
}
|
||||
b"author" => {
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.author.unwrap_or("unknown author")
|
||||
parser.app.author.unwrap_or("unknown author")
|
||||
)?;
|
||||
}
|
||||
b"about" => {
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.about.unwrap_or("unknown about")
|
||||
parser.app.about.unwrap_or("unknown about")
|
||||
)?;
|
||||
}
|
||||
b"long-about" => {
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.long_about.unwrap_or("unknown about")
|
||||
parser.app.long_about.unwrap_or("unknown about")
|
||||
)?;
|
||||
}
|
||||
b"usage" => {
|
||||
write!(self.writer, "{}", usage::create_usage_no_title(parser, &[]))?;
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
Usage::new(parser).create_usage_no_title(&[])
|
||||
)?;
|
||||
}
|
||||
b"all-args" => {
|
||||
self.write_all_args(parser)?;
|
||||
}
|
||||
b"unified" => {
|
||||
let opts_flags = parser
|
||||
.flags()
|
||||
.map(as_arg_trait)
|
||||
.chain(parser.opts().map(as_arg_trait));
|
||||
let opts_flags = parser.app.args.iter().filter(|a| a.has_switch());
|
||||
self.write_args(opts_flags)?;
|
||||
}
|
||||
b"flags" => {
|
||||
self.write_args(parser.flags().map(as_arg_trait))?;
|
||||
self.write_args(flags!(parser.app))?;
|
||||
}
|
||||
b"options" => {
|
||||
self.write_args(parser.opts().map(as_arg_trait))?;
|
||||
self.write_args(opts!(parser.app))?;
|
||||
}
|
||||
b"positionals" => {
|
||||
self.write_args(parser.positionals().map(as_arg_trait))?;
|
||||
self.write_args(positionals!(parser.app))?;
|
||||
}
|
||||
b"subcommands" => {
|
||||
self.write_subcommands(parser)?;
|
||||
self.write_subcommands(parser.app)?;
|
||||
}
|
||||
b"after-help" => {
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.more_help.unwrap_or("unknown after-help")
|
||||
parser.app.more_help.unwrap_or("unknown after-help")
|
||||
)?;
|
||||
}
|
||||
b"before-help" => {
|
||||
write!(
|
||||
self.writer,
|
||||
"{}",
|
||||
parser.meta.pre_help.unwrap_or("unknown before-help")
|
||||
parser.app.pre_help.unwrap_or("unknown before-help")
|
||||
)?;
|
||||
}
|
||||
// Unknown tag, write it back.
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct AppMeta<'b> {
|
||||
pub name: String,
|
||||
pub bin_name: Option<String>,
|
||||
pub author: Option<&'b str>,
|
||||
pub version: Option<&'b str>,
|
||||
pub long_version: Option<&'b str>,
|
||||
pub about: Option<&'b str>,
|
||||
pub long_about: Option<&'b str>,
|
||||
pub more_help: Option<&'b str>,
|
||||
pub pre_help: Option<&'b str>,
|
||||
pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
|
||||
pub usage_str: Option<&'b str>,
|
||||
pub usage: Option<String>,
|
||||
pub help_str: Option<&'b str>,
|
||||
pub disp_ord: usize,
|
||||
pub term_w: Option<usize>,
|
||||
pub max_w: Option<usize>,
|
||||
pub template: Option<&'b str>,
|
||||
}
|
||||
|
||||
impl<'b> AppMeta<'b> {
|
||||
pub fn new() -> Self { Default::default() }
|
||||
pub fn with_name(s: String) -> Self {
|
||||
AppMeta {
|
||||
name: s,
|
||||
disp_ord: 999,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
734
src/app/mod.rs
734
src/app/mod.rs
File diff suppressed because it is too large
Load diff
1991
src/app/parser.rs
1991
src/app/parser.rs
File diff suppressed because it is too large
Load diff
849
src/app/usage.rs
849
src/app/usage.rs
|
@ -3,477 +3,468 @@ use std::collections::{BTreeMap, VecDeque};
|
|||
|
||||
// Internal
|
||||
use INTERNAL_ERROR_MSG;
|
||||
use args::{AnyArg, ArgMatcher, PosBuilder};
|
||||
use args::{Arg, ArgMatcher};
|
||||
use args::settings::ArgSettings;
|
||||
use app::settings::AppSettings as AS;
|
||||
use app::parser::Parser;
|
||||
|
||||
// Creates a usage string for display. This happens just after all arguments were parsed, but before
|
||||
// any subcommands have been parsed (so as to give subcommands their own usage recursively)
|
||||
pub fn create_usage_with_title(p: &Parser, used: &[&str]) -> String {
|
||||
debugln!("usage::create_usage_with_title;");
|
||||
let mut usage = String::with_capacity(75);
|
||||
usage.push_str("USAGE:\n ");
|
||||
usage.push_str(&*create_usage_no_title(p, used));
|
||||
usage
|
||||
}
|
||||
pub struct Usage<'a, 'b, 'c, 'z>(&'z Parser<'a, 'b, 'c>)
|
||||
where
|
||||
'a: 'b,
|
||||
'b: 'c,
|
||||
'c: 'z;
|
||||
|
||||
// Creates a usage string to be used in error message (i.e. one with currently used args)
|
||||
pub fn create_error_usage<'a, 'b>(
|
||||
p: &Parser<'a, 'b>,
|
||||
matcher: &'b ArgMatcher<'a>,
|
||||
extra: Option<&str>,
|
||||
) -> String {
|
||||
let mut args: Vec<_> = matcher
|
||||
.arg_names()
|
||||
.iter()
|
||||
.filter(|n| {
|
||||
if let Some(o) = find_by_name!(p, **n, opts, iter) {
|
||||
!o.b.is_set(ArgSettings::Required) && !o.b.is_set(ArgSettings::Hidden)
|
||||
} else if let Some(p) = find_by_name!(p, **n, positionals, values) {
|
||||
!p.b.is_set(ArgSettings::Required) && p.b.is_set(ArgSettings::Hidden)
|
||||
} else {
|
||||
true // flags can't be required, so they're always true
|
||||
}
|
||||
})
|
||||
.map(|&n| n)
|
||||
.collect();
|
||||
if let Some(r) = extra {
|
||||
args.push(r);
|
||||
}
|
||||
create_usage_with_title(p, &*args)
|
||||
}
|
||||
impl<'a, 'b, 'c, 'z> Usage<'a, 'b, 'c, 'z> {
|
||||
pub fn new(p: &'z Parser<'a, 'b, 'c>) -> Self { Usage(p) }
|
||||
|
||||
// Creates a usage string (*without title*) if one was not provided by the user manually.
|
||||
pub fn create_usage_no_title(p: &Parser, used: &[&str]) -> String {
|
||||
debugln!("usage::create_usage_no_title;");
|
||||
if let Some(u) = p.meta.usage_str {
|
||||
String::from(&*u)
|
||||
} else if used.is_empty() {
|
||||
create_help_usage(p, true)
|
||||
} else {
|
||||
create_smart_usage(p, used)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a usage string for display in help messages (i.e. not for errors)
|
||||
pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
|
||||
let mut usage = String::with_capacity(75);
|
||||
let name = p.meta
|
||||
.usage
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name));
|
||||
usage.push_str(&*name);
|
||||
let req_string = if incl_reqs {
|
||||
let mut reqs: Vec<&str> = p.required().map(|r| &**r).collect();
|
||||
reqs.sort();
|
||||
reqs.dedup();
|
||||
get_required_usage_from(p, &reqs, None, None, false)
|
||||
.iter()
|
||||
.fold(String::new(), |a, s| a + &format!(" {}", s)[..])
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let flags = needs_flags_tag(p);
|
||||
if flags && !p.is_set(AS::UnifiedHelpMessage) {
|
||||
usage.push_str(" [FLAGS]");
|
||||
} else if flags {
|
||||
usage.push_str(" [OPTIONS]");
|
||||
}
|
||||
if !p.is_set(AS::UnifiedHelpMessage) && p.opts.iter().any(|o| {
|
||||
!o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden)
|
||||
}) {
|
||||
usage.push_str(" [OPTIONS]");
|
||||
// Creates a usage string for display. This happens just after all arguments were parsed, but before
|
||||
// any subcommands have been parsed (so as to give subcommands their own usage recursively)
|
||||
pub fn create_usage_with_title(&self, used: &[&str]) -> String {
|
||||
debugln!("usage::create_usage_with_title;");
|
||||
let mut usage = String::with_capacity(75);
|
||||
usage.push_str("USAGE:\n ");
|
||||
usage.push_str(&*self.create_usage_no_title(used));
|
||||
usage
|
||||
}
|
||||
|
||||
usage.push_str(&req_string[..]);
|
||||
|
||||
let has_last = p.positionals.values().any(|p| p.is_set(ArgSettings::Last));
|
||||
// places a '--' in the usage string if there are args and options
|
||||
// supporting multiple values
|
||||
if p.opts.iter().any(|o| o.is_set(ArgSettings::Multiple))
|
||||
&& p.positionals
|
||||
.values()
|
||||
.any(|p| !p.is_set(ArgSettings::Required))
|
||||
&& !(p.has_visible_subcommands() || p.is_set(AS::AllowExternalSubcommands))
|
||||
&& !has_last
|
||||
{
|
||||
usage.push_str(" [--]");
|
||||
// Creates a usage string to be used in error message (i.e. one with currently used args)
|
||||
pub fn create_error_usage(&self, matcher: &ArgMatcher<'a>, extra: Option<&str>) -> String {
|
||||
let mut args: Vec<_> = matcher
|
||||
.arg_names()
|
||||
.filter(|ref n| {
|
||||
if let Some(a) = find!(self.0.app, **n) {
|
||||
!a.is_set(ArgSettings::Required) && !a.is_set(ArgSettings::Hidden)
|
||||
} else {
|
||||
true // flags can't be required, so they're always true
|
||||
}
|
||||
})
|
||||
.map(|&n| n)
|
||||
.collect();
|
||||
if let Some(r) = extra {
|
||||
args.push(r);
|
||||
}
|
||||
self.create_usage_with_title(&*args)
|
||||
}
|
||||
let not_req_or_hidden = |p: &PosBuilder| {
|
||||
(!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last))
|
||||
&& !p.is_set(ArgSettings::Hidden)
|
||||
};
|
||||
if p.has_positionals() && p.positionals.values().any(not_req_or_hidden) {
|
||||
if let Some(args_tag) = get_args_tag(p, incl_reqs) {
|
||||
usage.push_str(&*args_tag);
|
||||
|
||||
// Creates a usage string (*without title*) if one was not provided by the user manually.
|
||||
pub fn create_usage_no_title(&self, used: &[&str]) -> String {
|
||||
debugln!("usage::create_usage_no_title;");
|
||||
if let Some(u) = self.0.app.usage_str {
|
||||
String::from(&*u)
|
||||
} else if used.is_empty() {
|
||||
self.create_help_usage(true)
|
||||
} else {
|
||||
usage.push_str(" [ARGS]");
|
||||
}
|
||||
if has_last && incl_reqs {
|
||||
let pos = p.positionals
|
||||
.values()
|
||||
.find(|p| p.b.is_set(ArgSettings::Last))
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
debugln!("usage::create_help_usage: '{}' has .last(true)", pos.name());
|
||||
let req = pos.is_set(ArgSettings::Required);
|
||||
if req
|
||||
&& p.positionals
|
||||
.values()
|
||||
.any(|p| !p.is_set(ArgSettings::Required))
|
||||
{
|
||||
usage.push_str(" -- <");
|
||||
} else if req {
|
||||
usage.push_str(" [--] <");
|
||||
} else {
|
||||
usage.push_str(" [-- <");
|
||||
}
|
||||
usage.push_str(&*pos.name_no_brackets());
|
||||
usage.push_str(">");
|
||||
usage.push_str(pos.multiple_str());
|
||||
if !req {
|
||||
usage.push_str("]");
|
||||
}
|
||||
self.create_smart_usage(used)
|
||||
}
|
||||
}
|
||||
|
||||
// incl_reqs is only false when this function is called recursively
|
||||
if p.has_visible_subcommands() && incl_reqs || p.is_set(AS::AllowExternalSubcommands) {
|
||||
if p.is_set(AS::SubcommandsNegateReqs) || p.is_set(AS::ArgsNegateSubcommands) {
|
||||
if !p.is_set(AS::ArgsNegateSubcommands) {
|
||||
usage.push_str("\n ");
|
||||
usage.push_str(&*create_help_usage(p, false));
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
} else {
|
||||
usage.push_str("\n ");
|
||||
usage.push_str(&*name);
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
}
|
||||
} else if p.is_set(AS::SubcommandRequired) || p.is_set(AS::SubcommandRequiredElseHelp) {
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
} else {
|
||||
usage.push_str(" [SUBCOMMAND]");
|
||||
}
|
||||
}
|
||||
usage.shrink_to_fit();
|
||||
debugln!("usage::create_help_usage: usage={}", usage);
|
||||
usage
|
||||
}
|
||||
|
||||
// Creates a context aware usage string, or "smart usage" from currently used
|
||||
// args, and requirements
|
||||
fn create_smart_usage(p: &Parser, used: &[&str]) -> String {
|
||||
debugln!("usage::smart_usage;");
|
||||
let mut usage = String::with_capacity(75);
|
||||
let mut hs: Vec<&str> = p.required().map(|s| &**s).collect();
|
||||
hs.extend_from_slice(used);
|
||||
|
||||
let r_string = get_required_usage_from(p, &hs, None, None, false)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
|
||||
|
||||
usage.push_str(
|
||||
&p.meta
|
||||
// Creates a usage string for display in help messages (i.e. not for errors)
|
||||
pub fn create_help_usage(&self, incl_reqs: bool) -> String {
|
||||
let mut usage = String::with_capacity(75);
|
||||
let name = self.0
|
||||
.app
|
||||
.usage
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name))[..],
|
||||
);
|
||||
usage.push_str(&*r_string);
|
||||
if p.is_set(AS::SubcommandRequired) {
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
}
|
||||
usage.shrink_to_fit();
|
||||
usage
|
||||
}
|
||||
.unwrap_or_else(|| self.0.app.bin_name.as_ref().unwrap_or(&self.0.app.name));
|
||||
usage.push_str(&*name);
|
||||
let req_string = if incl_reqs {
|
||||
let mut reqs: Vec<&str> = self.0.required().map(|r| &**r).collect();
|
||||
reqs.sort();
|
||||
reqs.dedup();
|
||||
self.get_required_usage_from(&reqs, None, None, false)
|
||||
.iter()
|
||||
.fold(String::new(), |a, s| a + &format!(" {}", s)[..])
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// Gets the `[ARGS]` tag for the usage string
|
||||
fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option<String> {
|
||||
debugln!("usage::get_args_tag;");
|
||||
let mut count = 0;
|
||||
'outer: for pos in p.positionals
|
||||
.values()
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
{
|
||||
debugln!("usage::get_args_tag:iter:{}:", pos.b.name);
|
||||
if let Some(g_vec) = p.groups_for_arg(pos.b.name) {
|
||||
for grp_s in &g_vec {
|
||||
debugln!("usage::get_args_tag:iter:{}:iter:{};", pos.b.name, grp_s);
|
||||
// if it's part of a required group we don't want to count it
|
||||
if p.groups.iter().any(|g| g.required && (&g.name == grp_s)) {
|
||||
continue 'outer;
|
||||
let flags = self.needs_flags_tag();
|
||||
if flags && !self.0.is_set(AS::UnifiedHelpMessage) {
|
||||
usage.push_str(" [FLAGS]");
|
||||
} else if flags {
|
||||
usage.push_str(" [OPTIONS]");
|
||||
}
|
||||
if !self.0.is_set(AS::UnifiedHelpMessage)
|
||||
&& opts!(self.0.app)
|
||||
.any(|o| !o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden))
|
||||
{
|
||||
usage.push_str(" [OPTIONS]");
|
||||
}
|
||||
|
||||
usage.push_str(&req_string[..]);
|
||||
|
||||
let has_last = positionals!(self.0.app).any(|p| p.is_set(ArgSettings::Last));
|
||||
// places a '--' in the usage string if there are args and options
|
||||
// supporting multiple values
|
||||
if opts!(self.0.app).any(|o| o.is_set(ArgSettings::Multiple))
|
||||
&& positionals!(self.0.app).any(|p| !p.is_set(ArgSettings::Required))
|
||||
&& !(self.0.app.has_visible_subcommands()
|
||||
|| self.0.is_set(AS::AllowExternalSubcommands)) && !has_last
|
||||
{
|
||||
usage.push_str(" [--]");
|
||||
}
|
||||
let not_req_or_hidden = |p: &Arg| {
|
||||
(!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last))
|
||||
&& !p.is_set(ArgSettings::Hidden)
|
||||
};
|
||||
if positionals!(self.0.app).any(not_req_or_hidden) {
|
||||
if let Some(args_tag) = self.get_args_tag(incl_reqs) {
|
||||
usage.push_str(&*args_tag);
|
||||
} else {
|
||||
usage.push_str(" [ARGS]");
|
||||
}
|
||||
if has_last && incl_reqs {
|
||||
let pos = positionals!(self.0.app)
|
||||
.find(|p| p.is_set(ArgSettings::Last))
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
debugln!("usage::create_help_usage: '{}' has .last(true)", pos.name);
|
||||
let req = pos.is_set(ArgSettings::Required);
|
||||
if req && positionals!(self.0.app).any(|p| !p.is_set(ArgSettings::Required)) {
|
||||
usage.push_str(" -- <");
|
||||
} else if req {
|
||||
usage.push_str(" [--] <");
|
||||
} else {
|
||||
usage.push_str(" [-- <");
|
||||
}
|
||||
usage.push_str(&*pos.name_no_brackets());
|
||||
usage.push_str(">");
|
||||
usage.push_str(pos.multiple_str());
|
||||
if !req {
|
||||
usage.push_str("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
debugln!(
|
||||
"usage::get_args_tag:iter: {} Args not required or hidden",
|
||||
count
|
||||
);
|
||||
}
|
||||
if !p.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
|
||||
debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]");
|
||||
return None; // [ARGS]
|
||||
} else if count == 1 && incl_reqs {
|
||||
let pos = p.positionals
|
||||
.values()
|
||||
.find(|pos| {
|
||||
!pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden)
|
||||
&& !pos.is_set(ArgSettings::Last)
|
||||
})
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
debugln!(
|
||||
"usage::get_args_tag:iter: Exactly one, returning '{}'",
|
||||
pos.name()
|
||||
);
|
||||
return Some(format!(
|
||||
" [{}]{}",
|
||||
pos.name_no_brackets(),
|
||||
pos.multiple_str()
|
||||
));
|
||||
} else if p.is_set(AS::DontCollapseArgsInUsage) && !p.positionals.is_empty() && incl_reqs {
|
||||
debugln!("usage::get_args_tag:iter: Don't collapse returning all");
|
||||
return Some(
|
||||
p.positionals
|
||||
.values()
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
.map(|pos| {
|
||||
format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(""),
|
||||
);
|
||||
} else if !incl_reqs {
|
||||
debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
|
||||
let highest_req_pos = p.positionals
|
||||
.iter()
|
||||
.filter_map(|(idx, pos)| {
|
||||
if pos.b.is_set(ArgSettings::Required) && !pos.b.is_set(ArgSettings::Last) {
|
||||
Some(idx)
|
||||
|
||||
// incl_reqs is only false when this function is called recursively
|
||||
if self.0.app.has_visible_subcommands() && incl_reqs
|
||||
|| self.0.is_set(AS::AllowExternalSubcommands)
|
||||
{
|
||||
if self.0.is_set(AS::SubcommandsNegateReqs) || self.0.is_set(AS::ArgsNegateSubcommands)
|
||||
{
|
||||
if !self.0.is_set(AS::ArgsNegateSubcommands) {
|
||||
usage.push_str("\n ");
|
||||
usage.push_str(&*self.create_help_usage(false));
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
} else {
|
||||
None
|
||||
usage.push_str("\n ");
|
||||
usage.push_str(&*name);
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
}
|
||||
})
|
||||
.max()
|
||||
.unwrap_or_else(|| p.positionals.len());
|
||||
return Some(
|
||||
p.positionals
|
||||
.iter()
|
||||
.filter_map(|(idx, pos)| {
|
||||
if idx <= highest_req_pos {
|
||||
Some(pos)
|
||||
} else if self.0.is_set(AS::SubcommandRequired)
|
||||
|| self.0.is_set(AS::SubcommandRequiredElseHelp)
|
||||
{
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
} else {
|
||||
usage.push_str(" [SUBCOMMAND]");
|
||||
}
|
||||
}
|
||||
usage.shrink_to_fit();
|
||||
debugln!("usage::create_help_usage: usage={}", usage);
|
||||
usage
|
||||
}
|
||||
|
||||
// Creates a context aware usage string, or "smart usage" from currently used
|
||||
// args, and requirements
|
||||
fn create_smart_usage(&self, used: &[&str]) -> String {
|
||||
debugln!("usage::smart_usage;");
|
||||
let mut usage = String::with_capacity(75);
|
||||
let mut hs: Vec<&str> = self.0.required().map(|s| &**s).collect();
|
||||
hs.extend_from_slice(used);
|
||||
|
||||
let r_string = self.get_required_usage_from(&hs, None, None, false)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
|
||||
|
||||
usage.push_str(
|
||||
&self.0
|
||||
.app
|
||||
.usage
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| self.0.app.bin_name.as_ref().unwrap_or(&self.0.app.name))[..],
|
||||
);
|
||||
usage.push_str(&*r_string);
|
||||
if self.0.is_set(AS::SubcommandRequired) {
|
||||
usage.push_str(" <SUBCOMMAND>");
|
||||
}
|
||||
usage.shrink_to_fit();
|
||||
usage
|
||||
}
|
||||
|
||||
// Gets the `[ARGS]` tag for the usage string
|
||||
fn get_args_tag(&self, incl_reqs: bool) -> Option<String> {
|
||||
debugln!("usage::get_args_tag;");
|
||||
let mut count = 0;
|
||||
'outer: for pos in positionals!(self.0.app)
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
{
|
||||
debugln!("usage::get_args_tag:iter:{}:", pos.name);
|
||||
if let Some(g_vec) = self.0.groups_for_arg(pos.name) {
|
||||
for grp_s in &g_vec {
|
||||
debugln!("usage::get_args_tag:iter:{}:iter:{};", pos.name, grp_s);
|
||||
// if it's part of a required group we don't want to count it
|
||||
if groups!(self.0.app).any(|g| g.required && (&g.name == grp_s)) {
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
debugln!(
|
||||
"usage::get_args_tag:iter: {} Args not required or hidden",
|
||||
count
|
||||
);
|
||||
}
|
||||
if !self.0.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
|
||||
debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]");
|
||||
return None; // [ARGS]
|
||||
} else if count == 1 && incl_reqs {
|
||||
let pos = positionals!(self.0.app)
|
||||
.find(|pos| {
|
||||
!pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden)
|
||||
&& !pos.is_set(ArgSettings::Last)
|
||||
})
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
debugln!(
|
||||
"usage::get_args_tag:iter: Exactly one, returning '{}'",
|
||||
pos.name
|
||||
);
|
||||
return Some(format!(
|
||||
" [{}]{}",
|
||||
pos.name_no_brackets(),
|
||||
pos.multiple_str()
|
||||
));
|
||||
} else if self.0.is_set(AS::DontCollapseArgsInUsage) && self.0.has_positionals()
|
||||
&& incl_reqs
|
||||
{
|
||||
debugln!("usage::get_args_tag:iter: Don't collapse returning all");
|
||||
return Some(
|
||||
positionals!(self.0.app)
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
.map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(""),
|
||||
);
|
||||
} else if !incl_reqs {
|
||||
debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
|
||||
let highest_req_pos = positionals!(self.0.app)
|
||||
.filter_map(|pos| {
|
||||
if pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Last) {
|
||||
Some(pos.index)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
.map(|pos| {
|
||||
format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(""),
|
||||
);
|
||||
.max()
|
||||
.unwrap_or_else(|| Some(positionals!(self.0.app).count() as u64));
|
||||
return Some(
|
||||
positionals!(self.0.app)
|
||||
.filter_map(|pos| {
|
||||
if pos.index <= highest_req_pos {
|
||||
Some(pos)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Required))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Hidden))
|
||||
.filter(|pos| !pos.is_set(ArgSettings::Last))
|
||||
.map(|pos| format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(""),
|
||||
);
|
||||
}
|
||||
Some("".into())
|
||||
}
|
||||
Some("".into())
|
||||
}
|
||||
|
||||
// Determines if we need the `[FLAGS]` tag in the usage string
|
||||
fn needs_flags_tag(p: &Parser) -> bool {
|
||||
debugln!("usage::needs_flags_tag;");
|
||||
'outer: for f in &p.flags {
|
||||
debugln!("usage::needs_flags_tag:iter: f={};", f.b.name);
|
||||
if let Some(l) = f.s.long {
|
||||
if l == "help" || l == "version" {
|
||||
// Don't print `[FLAGS]` just for help or version
|
||||
// Determines if we need the `[FLAGS]` tag in the usage string
|
||||
fn needs_flags_tag(&self) -> bool {
|
||||
debugln!("usage::needs_flags_tag;");
|
||||
'outer: for f in flags!(self.0.app) {
|
||||
debugln!("usage::needs_flags_tag:iter: f={};", f.name);
|
||||
if let Some(l) = f.long {
|
||||
if l == "help" || l == "version" {
|
||||
// Don't print `[FLAGS]` just for help or version
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(g_vec) = self.0.groups_for_arg(f.name) {
|
||||
for grp_s in &g_vec {
|
||||
debugln!("usage::needs_flags_tag:iter:iter: grp_s={};", grp_s);
|
||||
if groups!(self.0.app).any(|g| &g.name == grp_s && g.required) {
|
||||
debugln!("usage::needs_flags_tag:iter:iter: Group is required");
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if f.is_set(ArgSettings::Hidden) {
|
||||
continue;
|
||||
}
|
||||
debugln!("usage::needs_flags_tag:iter: [FLAGS] required");
|
||||
return true;
|
||||
}
|
||||
if let Some(g_vec) = p.groups_for_arg(f.b.name) {
|
||||
for grp_s in &g_vec {
|
||||
debugln!("usage::needs_flags_tag:iter:iter: grp_s={};", grp_s);
|
||||
if p.groups.iter().any(|g| &g.name == grp_s && g.required) {
|
||||
debugln!("usage::needs_flags_tag:iter:iter: Group is required");
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if f.is_set(ArgSettings::Hidden) {
|
||||
continue;
|
||||
}
|
||||
debugln!("usage::needs_flags_tag:iter: [FLAGS] required");
|
||||
return true;
|
||||
|
||||
debugln!("usage::needs_flags_tag: [FLAGS] not required");
|
||||
false
|
||||
}
|
||||
|
||||
debugln!("usage::needs_flags_tag: [FLAGS] not required");
|
||||
false
|
||||
}
|
||||
|
||||
// Returns the required args in usage string form by fully unrolling all groups
|
||||
pub fn get_required_usage_from<'a, 'b>(
|
||||
p: &Parser<'a, 'b>,
|
||||
reqs: &[&'a str],
|
||||
matcher: Option<&ArgMatcher<'a>>,
|
||||
extra: Option<&str>,
|
||||
incl_last: bool,
|
||||
) -> VecDeque<String> {
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: reqs={:?}, extra={:?}",
|
||||
reqs,
|
||||
extra
|
||||
);
|
||||
let mut desc_reqs: Vec<&str> = vec![];
|
||||
desc_reqs.extend(extra);
|
||||
let mut new_reqs: Vec<&str> = vec![];
|
||||
macro_rules! get_requires {
|
||||
(@group $a: ident, $v:ident, $p:ident) => {{
|
||||
if let Some(rl) = p.groups.iter()
|
||||
.filter(|g| g.requires.is_some())
|
||||
.find(|g| &g.name == $a)
|
||||
.map(|g| g.requires.as_ref().unwrap()) {
|
||||
for r in rl {
|
||||
if !$p.contains(&r) {
|
||||
debugln!("usage::get_required_usage_from:iter:{}: adding group req={:?}",
|
||||
$a, r);
|
||||
$v.push(r);
|
||||
// Returns the required args in usage string form by fully unrolling all groups
|
||||
pub fn get_required_usage_from(
|
||||
&self,
|
||||
reqs: &[&str],
|
||||
matcher: Option<&ArgMatcher<'a>>,
|
||||
extra: Option<&str>,
|
||||
incl_last: bool,
|
||||
) -> VecDeque<String> {
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: reqs={:?}, extra={:?}",
|
||||
reqs,
|
||||
extra
|
||||
);
|
||||
let mut desc_reqs: Vec<&str> = vec![];
|
||||
desc_reqs.extend(extra);
|
||||
let mut new_reqs: Vec<&str> = vec![];
|
||||
macro_rules! get_requires {
|
||||
(@group $a: ident, $v:ident, $p:ident) => {{
|
||||
if let Some(rl) = groups!(self.0.app)
|
||||
.filter(|g| g.requires.is_some())
|
||||
.find(|g| &g.name == $a)
|
||||
.map(|g| g.requires.as_ref().unwrap()) {
|
||||
for r in rl {
|
||||
if !$p.contains(&r) {
|
||||
debugln!("usage::get_required_usage_from:iter:{}: adding group req={:?}",
|
||||
$a, r);
|
||||
$v.push(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
($a:ident, $what:ident, $how:ident, $v:ident, $p:ident) => {{
|
||||
if let Some(rl) = p.$what.$how()
|
||||
.filter(|a| a.b.requires.is_some())
|
||||
.find(|arg| &arg.b.name == $a)
|
||||
.map(|a| a.b.requires.as_ref().unwrap()) {
|
||||
for &(_, r) in rl.iter() {
|
||||
if !$p.contains(&r) {
|
||||
debugln!("usage::get_required_usage_from:iter:{}: adding arg req={:?}",
|
||||
$a, r);
|
||||
$v.push(r);
|
||||
}};
|
||||
($a:ident, $what:ident, $how:ident, $v:ident, $p:ident) => {{
|
||||
if let Some(rl) = $what!(self.0.app)
|
||||
.filter(|a| a.requires.is_some())
|
||||
.find(|arg| &arg.name == $a)
|
||||
.map(|a| a.requires.as_ref().unwrap()) {
|
||||
for &(_, r) in rl.iter() {
|
||||
if !$p.contains(&r) {
|
||||
debugln!("usage::get_required_usage_from:iter:{}: adding arg req={:?}",
|
||||
$a, r);
|
||||
$v.push(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
// initialize new_reqs
|
||||
for a in reqs {
|
||||
get_requires!(a, flags, iter, new_reqs, reqs);
|
||||
get_requires!(a, opts, iter, new_reqs, reqs);
|
||||
get_requires!(a, positionals, values, new_reqs, reqs);
|
||||
get_requires!(@group a, new_reqs, reqs);
|
||||
}
|
||||
desc_reqs.extend_from_slice(&*new_reqs);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after init desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
loop {
|
||||
let mut tmp = vec![];
|
||||
for a in &new_reqs {
|
||||
get_requires!(a, flags, iter, tmp, desc_reqs);
|
||||
get_requires!(a, opts, iter, tmp, desc_reqs);
|
||||
get_requires!(a, positionals, values, tmp, desc_reqs);
|
||||
get_requires!(@group a, tmp, desc_reqs);
|
||||
}};
|
||||
}
|
||||
if tmp.is_empty() {
|
||||
debugln!("usage::get_required_usage_from: no more children");
|
||||
break;
|
||||
// initialize new_reqs
|
||||
for a in reqs {
|
||||
get_requires!(a, flags, iter, new_reqs, reqs);
|
||||
get_requires!(a, opts, iter, new_reqs, reqs);
|
||||
get_requires!(a, positionals, values, new_reqs, reqs);
|
||||
get_requires!(@group a, new_reqs, reqs);
|
||||
}
|
||||
desc_reqs.extend_from_slice(&*new_reqs);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after init desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
loop {
|
||||
let mut tmp = vec![];
|
||||
for a in &new_reqs {
|
||||
get_requires!(a, flags, iter, tmp, desc_reqs);
|
||||
get_requires!(a, opts, iter, tmp, desc_reqs);
|
||||
get_requires!(a, positionals, values, tmp, desc_reqs);
|
||||
get_requires!(@group a, tmp, desc_reqs);
|
||||
}
|
||||
if tmp.is_empty() {
|
||||
debugln!("usage::get_required_usage_from: no more children");
|
||||
break;
|
||||
} else {
|
||||
debugln!("usage::get_required_usage_from: after iter tmp={:?}", tmp);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after iter new_reqs={:?}",
|
||||
new_reqs
|
||||
);
|
||||
desc_reqs.extend_from_slice(&*new_reqs);
|
||||
new_reqs.clear();
|
||||
new_reqs.extend_from_slice(&*tmp);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after iter desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
}
|
||||
}
|
||||
desc_reqs.extend_from_slice(reqs);
|
||||
desc_reqs.sort();
|
||||
desc_reqs.dedup();
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: final desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
let mut ret_val = VecDeque::new();
|
||||
let args_in_groups = groups!(self.0.app)
|
||||
.filter(|gn| desc_reqs.contains(&gn.name))
|
||||
.flat_map(|g| self.0.arg_names_in_group(g.name))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pmap = if let Some(m) = matcher {
|
||||
desc_reqs
|
||||
.iter()
|
||||
.filter(|a| self.0.positionals.values().any(|p| &p == a))
|
||||
.filter(|&pos| !m.contains(pos))
|
||||
.filter_map(|pos| find!(self.0.app, pos))
|
||||
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
|
||||
.filter(|pos| !args_in_groups.contains(&pos.name))
|
||||
.map(|pos| (pos.index.unwrap(), pos))
|
||||
.collect::<BTreeMap<u64, &Arg>>() // sort by index
|
||||
} else {
|
||||
debugln!("usage::get_required_usage_from: after iter tmp={:?}", tmp);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after iter new_reqs={:?}",
|
||||
new_reqs
|
||||
);
|
||||
desc_reqs.extend_from_slice(&*new_reqs);
|
||||
new_reqs.clear();
|
||||
new_reqs.extend_from_slice(&*tmp);
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: after iter desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
desc_reqs
|
||||
.iter()
|
||||
.filter(|a| self.0.positionals.values().any(|p| &p == a))
|
||||
.filter_map(|pos| find!(self.0.app, pos))
|
||||
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
|
||||
.filter(|pos| !args_in_groups.contains(&pos.name))
|
||||
.map(|pos| (pos.index.unwrap(), pos))
|
||||
.collect::<BTreeMap<u64, &Arg>>() // sort by index
|
||||
};
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: args_in_groups={:?}",
|
||||
args_in_groups
|
||||
);
|
||||
for &p in pmap.values() {
|
||||
let s = p.to_string();
|
||||
if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
|
||||
ret_val.push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
desc_reqs.extend_from_slice(reqs);
|
||||
desc_reqs.sort();
|
||||
desc_reqs.dedup();
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: final desc_reqs={:?}",
|
||||
desc_reqs
|
||||
);
|
||||
let mut ret_val = VecDeque::new();
|
||||
let args_in_groups = p.groups
|
||||
.iter()
|
||||
.filter(|gn| desc_reqs.contains(&gn.name))
|
||||
.flat_map(|g| p.arg_names_in_group(g.name))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pmap = if let Some(m) = matcher {
|
||||
desc_reqs
|
||||
for a in desc_reqs
|
||||
.iter()
|
||||
.filter(|a| p.positionals.values().any(|p| &&p.b.name == a))
|
||||
.filter(|&pos| !m.contains(pos))
|
||||
.filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
|
||||
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
|
||||
.filter(|pos| !args_in_groups.contains(&pos.b.name))
|
||||
.map(|pos| (pos.index, pos))
|
||||
.collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
|
||||
} else {
|
||||
desc_reqs
|
||||
.filter(|name| !positionals!(self.0.app).any(|p| &&p.name == name))
|
||||
.filter(|name| !groups!(self.0.app).any(|g| &&g.name == name))
|
||||
.filter(|name| !args_in_groups.contains(name))
|
||||
.filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name)))
|
||||
{
|
||||
debugln!("usage::get_required_usage_from:iter:{}:", a);
|
||||
let arg = find!(self.0.app, a)
|
||||
.map(|f| f.to_string())
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
ret_val.push_back(arg);
|
||||
}
|
||||
let mut g_vec: Vec<String> = vec![];
|
||||
for g in desc_reqs
|
||||
.iter()
|
||||
.filter(|a| p.positionals.values().any(|pos| &&pos.b.name == a))
|
||||
.filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
|
||||
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
|
||||
.filter(|pos| !args_in_groups.contains(&pos.b.name))
|
||||
.map(|pos| (pos.index, pos))
|
||||
.collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
|
||||
};
|
||||
debugln!(
|
||||
"usage::get_required_usage_from: args_in_groups={:?}",
|
||||
args_in_groups
|
||||
);
|
||||
for &p in pmap.values() {
|
||||
let s = p.to_string();
|
||||
if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
|
||||
ret_val.push_back(s);
|
||||
.filter(|n| groups!(self.0.app).any(|g| &&g.name == n))
|
||||
{
|
||||
let g_string = self.0.args_in_group(g).join("|");
|
||||
let elem = format!("<{}>", &g_string[..g_string.len()]);
|
||||
if !g_vec.contains(&elem) {
|
||||
g_vec.push(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
for a in desc_reqs
|
||||
.iter()
|
||||
.filter(|name| !p.positionals.values().any(|p| &&p.b.name == name))
|
||||
.filter(|name| !p.groups.iter().any(|g| &&g.name == name))
|
||||
.filter(|name| !args_in_groups.contains(name))
|
||||
.filter(|name| {
|
||||
!(matcher.is_some() && matcher.as_ref().unwrap().contains(name))
|
||||
}) {
|
||||
debugln!("usage::get_required_usage_from:iter:{}:", a);
|
||||
let arg = find_by_name!(p, *a, flags, iter)
|
||||
.map(|f| f.to_string())
|
||||
.unwrap_or_else(|| {
|
||||
find_by_name!(p, *a, opts, iter)
|
||||
.map(|o| o.to_string())
|
||||
.expect(INTERNAL_ERROR_MSG)
|
||||
});
|
||||
ret_val.push_back(arg);
|
||||
}
|
||||
let mut g_vec: Vec<String> = vec![];
|
||||
for g in desc_reqs
|
||||
.iter()
|
||||
.filter(|n| p.groups.iter().any(|g| &&g.name == n))
|
||||
{
|
||||
let g_string = p.args_in_group(g).join("|");
|
||||
let elem = format!("<{}>", &g_string[..g_string.len()]);
|
||||
if !g_vec.contains(&elem) {
|
||||
g_vec.push(elem);
|
||||
for g in g_vec {
|
||||
ret_val.push_back(g);
|
||||
}
|
||||
}
|
||||
for g in g_vec {
|
||||
ret_val.push_back(g);
|
||||
}
|
||||
|
||||
ret_val
|
||||
ret_val
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// std
|
||||
use std::fmt::Display;
|
||||
#[allow(unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
// Internal
|
||||
use INTERNAL_ERROR_MSG;
|
||||
use INVALID_UTF8;
|
||||
use args::{AnyArg, ArgMatcher, MatchedArg};
|
||||
use args::{Arg, ArgMatcher, MatchedArg};
|
||||
use args::settings::ArgSettings;
|
||||
use errors::{Error, ErrorKind};
|
||||
use errors::Result as ClapResult;
|
||||
|
@ -14,15 +13,16 @@ use osstringext::OsStrExt2;
|
|||
use app::settings::AppSettings as AS;
|
||||
use app::parser::{ParseResult, Parser};
|
||||
use fmt::{Colorizer, ColorizerOption};
|
||||
use app::usage;
|
||||
use app::usage::Usage;
|
||||
|
||||
pub struct Validator<'a, 'b, 'z>(&'z mut Parser<'a, 'b>)
|
||||
pub struct Validator<'a, 'b, 'c, 'z>(&'z mut Parser<'a, 'b, 'c>)
|
||||
where
|
||||
'a: 'b,
|
||||
'b: 'z;
|
||||
'b: 'c,
|
||||
'c: 'z;
|
||||
|
||||
impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
||||
pub fn new(p: &'z mut Parser<'a, 'b>) -> Self { Validator(p) }
|
||||
impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
|
||||
pub fn new(p: &'z mut Parser<'a, 'b, 'c>) -> Self { Validator(p) }
|
||||
|
||||
pub fn validate(
|
||||
&mut self,
|
||||
|
@ -36,23 +36,19 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
self.0.add_defaults(matcher)?;
|
||||
if let ParseResult::Opt(a) = needs_val_of {
|
||||
debugln!("Validator::validate: needs_val_of={:?}", a);
|
||||
let o = self.0
|
||||
.opts
|
||||
.iter()
|
||||
.find(|o| o.b.name == a)
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
let o = find!(self.0.app, &a).expect(INTERNAL_ERROR_MSG);
|
||||
self.validate_required(matcher)?;
|
||||
reqs_validated = true;
|
||||
let should_err = if let Some(v) = matcher.0.args.get(&*o.b.name) {
|
||||
v.vals.is_empty() && !(o.v.min_vals.is_some() && o.v.min_vals.unwrap() == 0)
|
||||
let should_err = if let Some(v) = matcher.0.args.get(&*o.name) {
|
||||
v.vals.is_empty() && !(o.min_vals.is_some() && o.min_vals.unwrap() == 0)
|
||||
} else {
|
||||
true
|
||||
};
|
||||
if should_err {
|
||||
return Err(Error::empty_value(
|
||||
o,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -73,21 +69,18 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
self.validate_required(matcher)?;
|
||||
}
|
||||
self.validate_matched_args(matcher)?;
|
||||
matcher.usage(usage::create_usage_with_title(self.0, &[]));
|
||||
matcher.usage(Usage::new(self.0).create_usage_with_title(&[]));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_values<A>(
|
||||
fn validate_arg_values(
|
||||
&self,
|
||||
arg: &A,
|
||||
arg: &Arg,
|
||||
ma: &MatchedArg,
|
||||
matcher: &ArgMatcher<'a>,
|
||||
) -> ClapResult<()>
|
||||
where
|
||||
A: AnyArg<'a, 'b> + Display,
|
||||
{
|
||||
debugln!("Validator::validate_arg_values: arg={:?}", arg.name());
|
||||
) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_arg_values: arg={:?}", arg.name);
|
||||
for val in &ma.vals {
|
||||
if self.0.is_set(AS::StrictUtf8) && val.to_str().is_none() {
|
||||
debugln!(
|
||||
|
@ -95,11 +88,11 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
val
|
||||
);
|
||||
return Err(Error::invalid_utf8(
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
if let Some(p_vals) = arg.possible_vals() {
|
||||
if let Some(ref p_vals) = arg.possible_vals {
|
||||
debugln!("Validator::validate_arg_values: possible_vals={:?}", p_vals);
|
||||
let val_str = val.to_string_lossy();
|
||||
let ok = if arg.is_set(ArgSettings::CaseInsensitive) {
|
||||
|
@ -112,38 +105,38 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
val_str,
|
||||
p_vals,
|
||||
arg,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
}
|
||||
if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_()
|
||||
&& matcher.contains(&*arg.name())
|
||||
&& matcher.contains(&*arg.name)
|
||||
{
|
||||
debugln!("Validator::validate_arg_values: illegal empty val found");
|
||||
return Err(Error::empty_value(
|
||||
arg,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
if let Some(vtor) = arg.validator() {
|
||||
if let Some(ref vtor) = arg.validator {
|
||||
debug!("Validator::validate_arg_values: checking validator...");
|
||||
if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
|
||||
sdebugln!("error");
|
||||
return Err(Error::value_validation(Some(arg), e, self.0.color()));
|
||||
return Err(Error::value_validation(Some(arg), e, self.0.app.color()));
|
||||
} else {
|
||||
sdebugln!("good");
|
||||
}
|
||||
}
|
||||
if let Some(vtor) = arg.validator_os() {
|
||||
if let Some(ref vtor) = arg.validator_os {
|
||||
debug!("Validator::validate_arg_values: checking validator_os...");
|
||||
if let Err(e) = vtor(val) {
|
||||
sdebugln!("error");
|
||||
return Err(Error::value_validation(
|
||||
Some(arg),
|
||||
(*e).to_string_lossy().to_string(),
|
||||
self.0.color(),
|
||||
self.0.app.color(),
|
||||
));
|
||||
} else {
|
||||
sdebugln!("good");
|
||||
|
@ -153,106 +146,50 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn build_err(&self, name: &str, matcher: &ArgMatcher) -> ClapResult<()> {
|
||||
fn build_conflict_err(&self, name: &str, matcher: &ArgMatcher<'a>) -> ClapResult<()> {
|
||||
debugln!("build_err!: name={}", name);
|
||||
let mut c_with = find_from!(self.0, &name, blacklist, &matcher);
|
||||
c_with = c_with.or(
|
||||
self.0.find_any_arg(&name).map_or(None, |aa| aa.blacklist())
|
||||
.map_or(None,
|
||||
|bl| bl.iter().find(|arg| matcher.contains(arg)))
|
||||
.map_or(None, |an| self.0.find_any_arg(an))
|
||||
.map_or(None, |aa| Some(format!("{}", aa)))
|
||||
);
|
||||
let mut c_with = find_from!(self.0.app, &name, blacklist, &matcher);
|
||||
c_with = c_with.or(find!(self.0.app, &name)
|
||||
.map_or(None, |ref aa| aa.blacklist.as_ref())
|
||||
.map_or(None, |ref bl| bl.iter().find(|arg| matcher.contains(arg)))
|
||||
.map_or(None, |an| find!(self.0.app, an))
|
||||
.map_or(None, |aa| Some(format!("{}", aa))));
|
||||
debugln!("build_err!: '{:?}' conflicts with '{}'", c_with, &name);
|
||||
// matcher.remove(&name);
|
||||
let usg = usage::create_error_usage(self.0, matcher, None);
|
||||
if let Some(f) = find_by_name!(self.0, name, flags, iter) {
|
||||
// matcher.remove(&name);
|
||||
let usg = Usage::new(self.0).create_error_usage(matcher, None);
|
||||
if let Some(f) = find!(self.0.app, &name) {
|
||||
debugln!("build_err!: It was a flag...");
|
||||
Err(Error::argument_conflict(f, c_with, &*usg, self.0.color()))
|
||||
} else if let Some(o) = find_by_name!(self.0, name, opts, iter) {
|
||||
debugln!("build_err!: It was an option...");
|
||||
Err(Error::argument_conflict(o, c_with, &*usg, self.0.color()))
|
||||
Err(Error::argument_conflict(
|
||||
f,
|
||||
c_with,
|
||||
&*usg,
|
||||
self.0.app.color(),
|
||||
))
|
||||
} else {
|
||||
match find_by_name!(self.0, name, positionals, values) {
|
||||
Some(p) => {
|
||||
debugln!("build_err!: It was a positional...");
|
||||
Err(Error::argument_conflict(p, c_with, &*usg, self.0.color()))
|
||||
},
|
||||
None => panic!(INTERNAL_ERROR_MSG)
|
||||
}
|
||||
panic!(INTERNAL_ERROR_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_blacklist(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
|
||||
fn validate_blacklist(&self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_blacklist;");
|
||||
let mut conflicts: Vec<&str> = vec![];
|
||||
for (&name, _) in matcher.iter() {
|
||||
for name in &self.gather_conflicts(matcher) {
|
||||
debugln!("Validator::validate_blacklist:iter:{};", name);
|
||||
if let Some(grps) = self.0.groups_for_arg(name) {
|
||||
for grp in &grps {
|
||||
if let Some(g) = self.0.groups.iter().find(|g| &g.name == grp) {
|
||||
if !g.multiple {
|
||||
for arg in &g.args {
|
||||
if arg == &name {
|
||||
continue;
|
||||
}
|
||||
conflicts.push(arg);
|
||||
}
|
||||
}
|
||||
if let Some(ref gc) = g.conflicts {
|
||||
conflicts.extend(&*gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(arg) = find_any_by_name!(self.0, name) {
|
||||
if let Some(bl) = arg.blacklist() {
|
||||
for conf in bl {
|
||||
if matcher.get(conf).is_some() {
|
||||
conflicts.push(conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debugln!("Validator::validate_blacklist:iter:{}:group;", name);
|
||||
let args = self.0.arg_names_in_group(name);
|
||||
for arg in &args {
|
||||
debugln!("Validator::validate_blacklist:iter:{}:group:iter:{};", name, arg);
|
||||
if let Some(bl) = find_any_by_name!(self.0, *arg).unwrap().blacklist() {
|
||||
for conf in bl {
|
||||
if matcher.get(conf).is_some() {
|
||||
conflicts.push(conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for name in &conflicts {
|
||||
debugln!(
|
||||
"Validator::validate_blacklist:iter:{}: Checking blacklisted arg",
|
||||
name
|
||||
);
|
||||
let mut should_err = false;
|
||||
if self.0.groups.iter().any(|g| &g.name == name) {
|
||||
debugln!(
|
||||
"Validator::validate_blacklist:iter:{}: groups contains it...",
|
||||
name
|
||||
);
|
||||
if groups!(self.0.app).any(|g| &g.name == name) {
|
||||
debugln!("Validator::validate_blacklist:iter:{}:group;", name);
|
||||
for n in self.0.arg_names_in_group(name) {
|
||||
debugln!(
|
||||
"Validator::validate_blacklist:iter:{}:iter:{}: looking in group...",
|
||||
"Validator::validate_blacklist:iter:{}:group:iter:{};",
|
||||
name,
|
||||
n
|
||||
);
|
||||
if matcher.contains(n) {
|
||||
debugln!(
|
||||
"Validator::validate_blacklist:iter:{}:iter:{}: matcher contains it...",
|
||||
"Validator::validate_blacklist:iter:{}:group:iter:{}: found;",
|
||||
name,
|
||||
n
|
||||
);
|
||||
return self.build_err(n, matcher);
|
||||
return self.build_conflict_err(n, matcher);
|
||||
}
|
||||
}
|
||||
} else if let Some(ma) = matcher.get(name) {
|
||||
|
@ -263,12 +200,66 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
should_err = ma.occurs > 0;
|
||||
}
|
||||
if should_err {
|
||||
return self.build_err(*name, matcher);
|
||||
return self.build_conflict_err(*name, matcher);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn gather_conflicts(&self, matcher: &mut ArgMatcher<'a>) -> Vec<&'a str> {
|
||||
debugln!("Validator::gather_conflicts;");
|
||||
let mut conflicts = vec![];
|
||||
for name in matcher.arg_names() {
|
||||
debugln!("Validator::gather_conflicts:iter:{};", name);
|
||||
if let Some(arg) = find!(self.0.app, name) {
|
||||
if let Some(ref bl) = arg.blacklist {
|
||||
for conf in bl {
|
||||
if matcher.get(conf).is_some() {
|
||||
conflicts.push(*conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(grps) = self.0.groups_for_arg(name) {
|
||||
for grp in &grps {
|
||||
if let Some(g) = find!(self.0.app, grp, groups) {
|
||||
if !g.multiple {
|
||||
for g_arg in &g.args {
|
||||
if &g_arg == &name {
|
||||
continue;
|
||||
}
|
||||
conflicts.push(g_arg);
|
||||
}
|
||||
}
|
||||
if let Some(ref gc) = g.conflicts {
|
||||
conflicts.extend(&*gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debugln!("Validator::gather_conflicts:iter:{}:group;", name);
|
||||
let args = self.0.arg_names_in_group(name);
|
||||
for arg in &args {
|
||||
debugln!(
|
||||
"Validator::gather_conflicts:iter:{}:group:iter:{};",
|
||||
name,
|
||||
arg
|
||||
);
|
||||
if let Some(ref bl) =
|
||||
find!(self.0.app, arg).expect(INTERNAL_ERROR_MSG).blacklist
|
||||
{
|
||||
for conf in bl {
|
||||
if matcher.get(conf).is_some() {
|
||||
conflicts.push(conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
conflicts
|
||||
}
|
||||
|
||||
fn validate_matched_args(&self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_matched_args;");
|
||||
for (name, ma) in matcher.iter() {
|
||||
|
@ -277,25 +268,13 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
name,
|
||||
ma.vals
|
||||
);
|
||||
if let Some(opt) = find_by_name!(self.0, *name, opts, iter) {
|
||||
self.validate_arg_num_vals(opt, ma, matcher)?;
|
||||
self.validate_arg_values(opt, ma, matcher)?;
|
||||
self.validate_arg_requires(opt, ma, matcher)?;
|
||||
self.validate_arg_num_occurs(opt, ma, matcher)?;
|
||||
} else if let Some(flag) = find_by_name!(self.0, *name, flags, iter) {
|
||||
self.validate_arg_requires(flag, ma, matcher)?;
|
||||
self.validate_arg_num_occurs(flag, ma, matcher)?;
|
||||
} else if let Some(pos) = find_by_name!(self.0, *name, positionals, values) {
|
||||
self.validate_arg_num_vals(pos, ma, matcher)?;
|
||||
self.validate_arg_num_occurs(pos, ma, matcher)?;
|
||||
self.validate_arg_values(pos, ma, matcher)?;
|
||||
self.validate_arg_requires(pos, ma, matcher)?;
|
||||
if let Some(arg) = find!(self.0.app, name) {
|
||||
self.validate_arg_num_vals(arg, ma, matcher)?;
|
||||
self.validate_arg_values(arg, ma, matcher)?;
|
||||
self.validate_arg_requires(arg, ma, matcher)?;
|
||||
self.validate_arg_num_occurs(arg, ma, matcher)?;
|
||||
} else {
|
||||
let grp = self.0
|
||||
.groups
|
||||
.iter()
|
||||
.find(|g| &g.name == name)
|
||||
.expect(INTERNAL_ERROR_MSG);
|
||||
let grp = find!(self.0.app, name, groups).expect(INTERNAL_ERROR_MSG);
|
||||
if let Some(ref g_reqs) = grp.requires {
|
||||
if g_reqs.iter().any(|&n| !matcher.contains(n)) {
|
||||
return self.missing_required_error(matcher, None);
|
||||
|
@ -306,38 +285,32 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_num_occurs<A>(
|
||||
fn validate_arg_num_occurs(
|
||||
&self,
|
||||
a: &A,
|
||||
a: &Arg,
|
||||
ma: &MatchedArg,
|
||||
matcher: &ArgMatcher,
|
||||
) -> ClapResult<()>
|
||||
where
|
||||
A: AnyArg<'a, 'b> + Display,
|
||||
{
|
||||
debugln!("Validator::validate_arg_num_occurs: a={};", a.name());
|
||||
matcher: &ArgMatcher<'a>,
|
||||
) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_arg_num_occurs: a={};", a.name);
|
||||
if ma.occurs > 1 && !a.is_set(ArgSettings::Multiple) {
|
||||
// Not the first time, and we don't allow multiples
|
||||
return Err(Error::unexpected_multiple_usage(
|
||||
a,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_num_vals<A>(
|
||||
fn validate_arg_num_vals(
|
||||
&self,
|
||||
a: &A,
|
||||
a: &Arg,
|
||||
ma: &MatchedArg,
|
||||
matcher: &ArgMatcher,
|
||||
) -> ClapResult<()>
|
||||
where
|
||||
A: AnyArg<'a, 'b> + Display,
|
||||
{
|
||||
matcher: &ArgMatcher<'a>,
|
||||
) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_arg_num_vals;");
|
||||
if let Some(num) = a.num_vals() {
|
||||
if let Some(num) = a.num_vals {
|
||||
debugln!("Validator::validate_arg_num_vals: num_vals set...{}", num);
|
||||
let should_err = if a.is_set(ArgSettings::Multiple) {
|
||||
((ma.vals.len() as u64) % num) != 0
|
||||
|
@ -361,12 +334,12 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
} else {
|
||||
"ere"
|
||||
},
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(num) = a.max_vals() {
|
||||
if let Some(num) = a.max_vals {
|
||||
debugln!("Validator::validate_arg_num_vals: max_vals set...{}", num);
|
||||
if (ma.vals.len() as u64) > num {
|
||||
debugln!("Validator::validate_arg_num_vals: Sending error TooManyValues");
|
||||
|
@ -378,12 +351,12 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
.to_str()
|
||||
.expect(INVALID_UTF8),
|
||||
a,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
}
|
||||
let min_vals_zero = if let Some(num) = a.min_vals() {
|
||||
let min_vals_zero = if let Some(num) = a.min_vals {
|
||||
debugln!("Validator::validate_arg_num_vals: min_vals set: {}", num);
|
||||
if (ma.vals.len() as u64) < num && num != 0 {
|
||||
debugln!("Validator::validate_arg_num_vals: Sending error TooFewValues");
|
||||
|
@ -391,8 +364,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
a,
|
||||
num,
|
||||
ma.vals.len(),
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
num == 0
|
||||
|
@ -401,27 +374,24 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
};
|
||||
// Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
|
||||
// Issue 1105 (https://github.com/kbknapp/clap-rs/issues/1105)
|
||||
if a.takes_value() && !min_vals_zero && ma.vals.is_empty() {
|
||||
if a.is_set(ArgSettings::TakesValue) && !min_vals_zero && ma.vals.is_empty() {
|
||||
return Err(Error::empty_value(
|
||||
a,
|
||||
&*usage::create_error_usage(self.0, matcher, None),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, None),
|
||||
self.0.app.color(),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_requires<A>(
|
||||
fn validate_arg_requires(
|
||||
&self,
|
||||
a: &A,
|
||||
a: &Arg,
|
||||
ma: &MatchedArg,
|
||||
matcher: &ArgMatcher,
|
||||
) -> ClapResult<()>
|
||||
where
|
||||
A: AnyArg<'a, 'b> + Display,
|
||||
{
|
||||
debugln!("Validator::validate_arg_requires:{};", a.name());
|
||||
if let Some(a_reqs) = a.requires() {
|
||||
matcher: &ArgMatcher<'a>,
|
||||
) -> ClapResult<()> {
|
||||
debugln!("Validator::validate_arg_requires:{};", a.name);
|
||||
if let Some(ref a_reqs) = a.requires {
|
||||
for &(val, name) in a_reqs.iter().filter(|&&(val, _)| val.is_some()) {
|
||||
let missing_req =
|
||||
|v| v == val.expect(INTERNAL_ERROR_MSG) && !matcher.contains(name);
|
||||
|
@ -438,7 +408,7 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_required(&self, matcher: &ArgMatcher) -> ClapResult<()> {
|
||||
fn validate_required(&self, matcher: &ArgMatcher<'a>) -> ClapResult<()> {
|
||||
debugln!(
|
||||
"Validator::validate_required: required={:?};",
|
||||
self.0.required
|
||||
|
@ -449,7 +419,7 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
if matcher.contains(name) {
|
||||
continue 'outer;
|
||||
}
|
||||
if let Some(a) = find_any_by_name!(self.0, *name) {
|
||||
if let Some(a) = find!(self.0.app, name) {
|
||||
if self.is_missing_required_ok(a, matcher) {
|
||||
continue 'outer;
|
||||
}
|
||||
|
@ -468,28 +438,32 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_arg_conflicts(&self, a: &AnyArg, matcher: &ArgMatcher) -> Option<bool> {
|
||||
debugln!("Validator::validate_arg_conflicts: a={:?};", a.name());
|
||||
a.blacklist().map(|bl| {
|
||||
bl.iter().any(|conf| {
|
||||
fn is_missing_required_ok(&self, a: &Arg<'a, 'b>, matcher: &ArgMatcher<'a>) -> bool {
|
||||
debugln!("Validator::is_missing_required_ok: a={}", a.name);
|
||||
self.validate_arg_conflicts(a, matcher).unwrap_or(false)
|
||||
|| self.validate_required_unless(a, matcher).unwrap_or(false)
|
||||
|| self.0.overriden.contains(&a.name)
|
||||
}
|
||||
|
||||
fn validate_arg_conflicts(&self, a: &Arg<'a, 'b>, matcher: &ArgMatcher<'a>) -> Option<bool> {
|
||||
debugln!("Validator::validate_arg_conflicts: a={:?};", a.name);
|
||||
a.blacklist.as_ref().map(|bl| {
|
||||
bl.iter().any(|ref conf| {
|
||||
matcher.contains(conf)
|
||||
|| self.0
|
||||
.groups
|
||||
.iter()
|
||||
.find(|g| &g.name == conf)
|
||||
|| find!(self.0.app, *conf, groups)
|
||||
.map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg)))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn validate_required_unless(&self, a: &AnyArg, matcher: &ArgMatcher) -> Option<bool> {
|
||||
debugln!("Validator::validate_required_unless: a={:?};", a.name());
|
||||
fn validate_required_unless(&self, a: &Arg<'a, 'b>, matcher: &ArgMatcher<'a>) -> Option<bool> {
|
||||
debugln!("Validator::validate_required_unless: a={:?};", a.name);
|
||||
macro_rules! check {
|
||||
($how:ident, $_self:expr, $a:ident, $m:ident) => {{
|
||||
$a.required_unless().map(|ru| {
|
||||
$a.r_unless.as_ref().map(|ru| {
|
||||
ru.iter().$how(|n| {
|
||||
$m.contains(n) || {
|
||||
if let Some(grp) = $_self.groups.iter().find(|g| &g.name == n) {
|
||||
if let Some(grp) = find!($_self.app, n, groups) {
|
||||
grp.args.iter().any(|arg| $m.contains(arg))
|
||||
} else {
|
||||
false
|
||||
|
@ -506,11 +480,15 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
}
|
||||
}
|
||||
|
||||
fn missing_required_error(&self, matcher: &ArgMatcher, extra: Option<&str>) -> ClapResult<()> {
|
||||
fn missing_required_error(
|
||||
&self,
|
||||
matcher: &ArgMatcher<'a>,
|
||||
extra: Option<&str>,
|
||||
) -> ClapResult<()> {
|
||||
debugln!("Validator::missing_required_error: extra={:?}", extra);
|
||||
let c = Colorizer::new(ColorizerOption {
|
||||
use_stderr: true,
|
||||
when: self.0.color(),
|
||||
when: self.0.app.color(),
|
||||
});
|
||||
let mut reqs = self.0.required.iter().map(|&r| &*r).collect::<Vec<_>>();
|
||||
if let Some(r) = extra {
|
||||
|
@ -519,27 +497,20 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
|
|||
reqs.retain(|n| !matcher.contains(n));
|
||||
reqs.dedup();
|
||||
debugln!("Validator::missing_required_error: reqs={:#?}", reqs);
|
||||
let req_args =
|
||||
usage::get_required_usage_from(self.0, &reqs[..], Some(matcher), extra, true)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| {
|
||||
acc + &format!("\n {}", c.error(s))[..]
|
||||
});
|
||||
let req_args = Usage::new(self.0)
|
||||
.get_required_usage_from(&reqs[..], Some(matcher), extra, true)
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| {
|
||||
acc + &format!("\n {}", c.error(s))[..]
|
||||
});
|
||||
debugln!(
|
||||
"Validator::missing_required_error: req_args={:#?}",
|
||||
req_args
|
||||
);
|
||||
Err(Error::missing_required_argument(
|
||||
&*req_args,
|
||||
&*usage::create_error_usage(self.0, matcher, extra),
|
||||
self.0.color(),
|
||||
&*Usage::new(self.0).create_error_usage(matcher, extra),
|
||||
self.0.app.color(),
|
||||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_missing_required_ok(&self, a: &AnyArg, matcher: &ArgMatcher) -> bool {
|
||||
debugln!("Validator::is_missing_required_ok: a={}", a.name());
|
||||
self.validate_arg_conflicts(a, matcher).unwrap_or(false)
|
||||
|| self.validate_required_unless(a, matcher).unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
// Std
|
||||
use std::rc::Rc;
|
||||
use std::fmt as std_fmt;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
|
||||
// Internal
|
||||
use args::settings::ArgSettings;
|
||||
use map::{self, VecMap};
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait AnyArg<'n, 'e>: std_fmt::Display {
|
||||
fn name(&self) -> &'n str;
|
||||
fn overrides(&self) -> Option<&[&'e str]>;
|
||||
fn aliases(&self) -> Option<Vec<&'e str>>;
|
||||
fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>;
|
||||
fn blacklist(&self) -> Option<&[&'e str]>;
|
||||
fn required_unless(&self) -> Option<&[&'e str]>;
|
||||
fn is_set(&self, ArgSettings) -> bool;
|
||||
fn set(&mut self, ArgSettings);
|
||||
fn has_switch(&self) -> bool;
|
||||
fn max_vals(&self) -> Option<u64>;
|
||||
fn min_vals(&self) -> Option<u64>;
|
||||
fn num_vals(&self) -> Option<u64>;
|
||||
fn possible_vals(&self) -> Option<&[&'e str]>;
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> Result<(), String>>>;
|
||||
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> Result<(), OsString>>>;
|
||||
fn short(&self) -> Option<char>;
|
||||
fn long(&self) -> Option<&'e str>;
|
||||
fn val_delim(&self) -> Option<char>;
|
||||
fn takes_value(&self) -> bool;
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>>;
|
||||
fn help(&self) -> Option<&'e str>;
|
||||
fn long_help(&self) -> Option<&'e str>;
|
||||
fn default_val(&self) -> Option<&'e OsStr>;
|
||||
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>;
|
||||
fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)>;
|
||||
fn longest_filter(&self) -> bool;
|
||||
fn val_terminator(&self) -> Option<&'e str>;
|
||||
}
|
||||
|
||||
pub trait DispOrder {
|
||||
fn disp_ord(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<'n, 'e, 'z, T: ?Sized> AnyArg<'n, 'e> for &'z T where T: AnyArg<'n, 'e> + 'z {
|
||||
fn name(&self) -> &'n str { (*self).name() }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { (*self).overrides() }
|
||||
fn aliases(&self) -> Option<Vec<&'e str>> { (*self).aliases() }
|
||||
fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { (*self).requires() }
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { (*self).blacklist() }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { (*self).required_unless() }
|
||||
fn is_set(&self, a: ArgSettings) -> bool { (*self).is_set(a) }
|
||||
fn set(&mut self, _: ArgSettings) { panic!(INTERNAL_ERROR_MSG) }
|
||||
fn has_switch(&self) -> bool { (*self).has_switch() }
|
||||
fn max_vals(&self) -> Option<u64> { (*self).max_vals() }
|
||||
fn min_vals(&self) -> Option<u64> { (*self).min_vals() }
|
||||
fn num_vals(&self) -> Option<u64> { (*self).num_vals() }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { (*self).possible_vals() }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> Result<(), String>>> { (*self).validator() }
|
||||
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> Result<(), OsString>>> { (*self).validator_os() }
|
||||
fn short(&self) -> Option<char> { (*self).short() }
|
||||
fn long(&self) -> Option<&'e str> { (*self).long() }
|
||||
fn val_delim(&self) -> Option<char> { (*self).val_delim() }
|
||||
fn takes_value(&self) -> bool { (*self).takes_value() }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { (*self).val_names() }
|
||||
fn help(&self) -> Option<&'e str> { (*self).help() }
|
||||
fn long_help(&self) -> Option<&'e str> { (*self).long_help() }
|
||||
fn default_val(&self) -> Option<&'e OsStr> { (*self).default_val() }
|
||||
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { (*self).default_vals_ifs() }
|
||||
fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { (*self).env() }
|
||||
fn longest_filter(&self) -> bool { (*self).longest_filter() }
|
||||
fn val_terminator(&self) -> Option<&'e str> { (*self).val_terminator() }
|
||||
}
|
574
src/args/arg.rs
574
src/args/arg.rs
|
@ -1,20 +1,23 @@
|
|||
#[cfg(feature = "yaml")]
|
||||
use std::collections::BTreeMap;
|
||||
use std::rc::Rc;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
#[cfg(target_os = "windows")]
|
||||
use osstringext::OsStrExt3;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::env;
|
||||
use std::cmp::{Ord, Ordering};
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
use yaml_rust::Yaml;
|
||||
use map::VecMap;
|
||||
|
||||
use usage_parser::UsageParser;
|
||||
use args::settings::ArgSettings;
|
||||
use args::arg_builder::{Base, Switched, Valued};
|
||||
use args::settings::{ArgFlags, ArgSettings};
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
/// The abstract representation of a command line argument. Used to set all the options and
|
||||
/// relationships that define a valid argument for the program.
|
||||
|
@ -44,11 +47,62 @@ pub struct Arg<'a, 'b>
|
|||
where
|
||||
'a: 'b,
|
||||
{
|
||||
#[doc(hidden)] pub b: Base<'a, 'b>,
|
||||
#[doc(hidden)] pub s: Switched<'b>,
|
||||
#[doc(hidden)] pub v: Valued<'a, 'b>,
|
||||
#[doc(hidden)] pub index: Option<u64>,
|
||||
#[doc(hidden)] pub r_ifs: Option<Vec<(&'a str, &'b str)>>,
|
||||
#[doc(hidden)]
|
||||
pub name: &'a str,
|
||||
#[doc(hidden)]
|
||||
pub help: Option<&'b str>,
|
||||
#[doc(hidden)]
|
||||
pub long_help: Option<&'b str>,
|
||||
#[doc(hidden)]
|
||||
pub blacklist: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub settings: ArgFlags,
|
||||
#[doc(hidden)]
|
||||
pub r_unless: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub overrides: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub groups: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub requires: Option<Vec<(Option<&'b str>, &'a str)>>,
|
||||
#[doc(hidden)]
|
||||
pub short: Option<char>,
|
||||
#[doc(hidden)]
|
||||
pub long: Option<&'b str>,
|
||||
#[doc(hidden)]
|
||||
pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
|
||||
#[doc(hidden)]
|
||||
pub disp_ord: usize,
|
||||
#[doc(hidden)]
|
||||
pub unified_ord: usize,
|
||||
#[doc(hidden)]
|
||||
pub possible_vals: Option<Vec<&'b str>>,
|
||||
#[doc(hidden)]
|
||||
pub val_names: Option<VecMap<&'b str>>,
|
||||
#[doc(hidden)]
|
||||
pub num_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub max_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub min_vals: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
|
||||
#[doc(hidden)]
|
||||
pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
|
||||
#[doc(hidden)]
|
||||
pub val_delim: Option<char>,
|
||||
#[doc(hidden)]
|
||||
pub default_val: Option<&'b OsStr>,
|
||||
#[doc(hidden)]
|
||||
pub default_vals_ifs: Option<VecMap<(&'a str, Option<&'b OsStr>, &'b OsStr)>>,
|
||||
#[doc(hidden)]
|
||||
pub env: Option<(&'a OsStr, Option<OsString>)>,
|
||||
#[doc(hidden)]
|
||||
pub terminator: Option<&'b str>,
|
||||
#[doc(hidden)]
|
||||
pub index: Option<u64>,
|
||||
#[doc(hidden)]
|
||||
pub r_ifs: Option<Vec<(&'a str, &'b str)>>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Arg<'a, 'b> {
|
||||
|
@ -71,7 +125,9 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn with_name(n: &'a str) -> Self {
|
||||
Arg {
|
||||
b: Base::new(n),
|
||||
name: n,
|
||||
disp_ord: 999,
|
||||
unified_ord: 999,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -146,8 +202,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
}
|
||||
s => panic!(
|
||||
"Unknown Arg setting '{}' in YAML file for arg '{}'",
|
||||
s,
|
||||
name_str
|
||||
s, name_str
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +383,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`short`]: ./struct.Arg.html#method.short
|
||||
pub fn short<S: AsRef<str>>(mut self, s: S) -> Self {
|
||||
self.s.short = s.as_ref().trim_left_matches(|c| c == '-').chars().nth(0);
|
||||
self.short = s.as_ref().trim_left_matches(|c| c == '-').chars().nth(0);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -368,7 +423,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert!(m.is_present("cfg"));
|
||||
/// ```
|
||||
pub fn long(mut self, l: &'b str) -> Self {
|
||||
self.s.long = Some(l.trim_left_matches(|c| c == '-'));
|
||||
self.long = Some(l.trim_left_matches(|c| c == '-'));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -394,10 +449,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn alias<S: Into<&'b str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.s.aliases {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
als.push((name.into(), false));
|
||||
} else {
|
||||
self.s.aliases = Some(vec![(name.into(), false)]);
|
||||
self.aliases = Some(vec![(name.into(), false)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -424,12 +479,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg`]: ./struct.Arg.html
|
||||
pub fn aliases(mut self, names: &[&'b str]) -> Self {
|
||||
if let Some(ref mut als) = self.s.aliases {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
for n in names {
|
||||
als.push((n, false));
|
||||
}
|
||||
} else {
|
||||
self.s.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
|
||||
self.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -455,10 +510,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [`App::alias`]: ./struct.Arg.html#method.alias
|
||||
pub fn visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self {
|
||||
if let Some(ref mut als) = self.s.aliases {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
als.push((name.into(), true));
|
||||
} else {
|
||||
self.s.aliases = Some(vec![(name.into(), true)]);
|
||||
self.aliases = Some(vec![(name.into(), true)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -482,12 +537,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg`]: ./struct.Arg.html
|
||||
/// [`App::aliases`]: ./struct.Arg.html#method.aliases
|
||||
pub fn visible_aliases(mut self, names: &[&'b str]) -> Self {
|
||||
if let Some(ref mut als) = self.s.aliases {
|
||||
if let Some(ref mut als) = self.aliases {
|
||||
for n in names {
|
||||
als.push((n, true));
|
||||
}
|
||||
} else {
|
||||
self.s.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
|
||||
self.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -543,7 +598,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg::long_help`]: ./struct.Arg.html#method.long_help
|
||||
pub fn help(mut self, h: &'b str) -> Self {
|
||||
self.b.help = Some(h);
|
||||
self.help = Some(h);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -614,7 +669,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg::help`]: ./struct.Arg.html#method.help
|
||||
pub fn long_help(mut self, h: &'b str) -> Self {
|
||||
self.b.long_help = Some(h);
|
||||
self.long_help = Some(h);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -940,10 +995,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::required`]: ./struct.Arg.html#method.required
|
||||
/// [`Arg::required_unless(name)`]: ./struct.Arg.html#method.required_unless
|
||||
pub fn required_unless(mut self, name: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.r_unless {
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.b.r_unless = Some(vec![name]);
|
||||
self.r_unless = Some(vec![name]);
|
||||
}
|
||||
self.required(true)
|
||||
}
|
||||
|
@ -1012,12 +1067,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::required_unless_one`]: ./struct.Arg.html#method.required_unless_one
|
||||
/// [`Arg::required_unless_all(names)`]: ./struct.Arg.html#method.required_unless_all
|
||||
pub fn required_unless_all(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.r_unless {
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.b.r_unless = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.r_unless = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self.setb(ArgSettings::RequiredUnlessAll);
|
||||
self.required(true)
|
||||
|
@ -1088,12 +1143,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::required_unless_one(names)`]: ./struct.Arg.html#method.required_unless_one
|
||||
/// [`Arg::required_unless_all`]: ./struct.Arg.html#method.required_unless_all
|
||||
pub fn required_unless_one(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.r_unless {
|
||||
if let Some(ref mut vec) = self.r_unless {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.b.r_unless = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.r_unless = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self.required(true)
|
||||
}
|
||||
|
@ -1136,10 +1191,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::ArgumentConflict);
|
||||
/// ```
|
||||
pub fn conflicts_with(mut self, name: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.blacklist {
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.b.blacklist = Some(vec![name]);
|
||||
self.blacklist = Some(vec![name]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1186,12 +1241,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg::conflicts_with`]: ./struct.Arg.html#method.conflicts_with
|
||||
pub fn conflicts_with_all(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.blacklist {
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.b.blacklist = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.blacklist = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1223,10 +1278,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert!(!m.is_present("flag"));
|
||||
/// ```
|
||||
pub fn overrides_with(mut self, name: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.overrides {
|
||||
if let Some(ref mut vec) = self.overrides {
|
||||
vec.push(name.as_ref());
|
||||
} else {
|
||||
self.b.overrides = Some(vec![name.as_ref()]);
|
||||
self.overrides = Some(vec![name.as_ref()]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1259,12 +1314,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert!(!m.is_present("flag"));
|
||||
/// ```
|
||||
pub fn overrides_with_all(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.overrides {
|
||||
if let Some(ref mut vec) = self.overrides {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.b.overrides = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.overrides = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1325,12 +1380,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires(mut self, name: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.requires {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push((None, name));
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
vec.push((None, name));
|
||||
self.b.requires = Some(vec);
|
||||
self.requires = Some(vec);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1395,10 +1450,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires_if(mut self, val: &'b str, arg: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.requires {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push((Some(val), arg));
|
||||
} else {
|
||||
self.b.requires = Some(vec![(Some(val), arg)]);
|
||||
self.requires = Some(vec![(Some(val), arg)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1455,7 +1510,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires_ifs(mut self, ifs: &[(&'b str, &'a str)]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.requires {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
for &(val, arg) in ifs {
|
||||
vec.push((Some(val), arg));
|
||||
}
|
||||
|
@ -1464,7 +1519,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
for &(val, arg) in ifs {
|
||||
vec.push((Some(val), arg));
|
||||
}
|
||||
self.b.requires = Some(vec);
|
||||
self.requires = Some(vec);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1699,7 +1754,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
/// [`Arg::requires_all(&[arg, arg2])`]: ./struct.Arg.html#method.requires_all
|
||||
pub fn requires_all(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.requires {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
for s in names {
|
||||
vec.push((None, s));
|
||||
}
|
||||
|
@ -1708,7 +1763,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
for s in names {
|
||||
vec.push((None, *s));
|
||||
}
|
||||
self.b.requires = Some(vec);
|
||||
self.requires = Some(vec);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2127,7 +2182,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`max_values`]: ./struct.Arg.html#method.max_values
|
||||
pub fn value_terminator(mut self, term: &'b str) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.v.terminator = Some(term);
|
||||
self.terminator = Some(term);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -2319,12 +2374,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [options]: ./struct.Arg.html#method.takes_value
|
||||
/// [positional arguments]: ./struct.Arg.html#method.index
|
||||
pub fn possible_values(mut self, names: &[&'b str]) -> Self {
|
||||
if let Some(ref mut vec) = self.v.possible_vals {
|
||||
if let Some(ref mut vec) = self.possible_vals {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.v.possible_vals = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.possible_vals = Some(names.iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2383,10 +2438,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [options]: ./struct.Arg.html#method.takes_value
|
||||
/// [positional arguments]: ./struct.Arg.html#method.index
|
||||
pub fn possible_value(mut self, name: &'b str) -> Self {
|
||||
if let Some(ref mut vec) = self.v.possible_vals {
|
||||
if let Some(ref mut vec) = self.possible_vals {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.v.possible_vals = Some(vec![name]);
|
||||
self.possible_vals = Some(vec![name]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2475,10 +2530,10 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`ArgGroup`]: ./struct.ArgGroup.html
|
||||
pub fn group(mut self, name: &'a str) -> Self {
|
||||
if let Some(ref mut vec) = self.b.groups {
|
||||
if let Some(ref mut vec) = self.groups {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.b.groups = Some(vec![name]);
|
||||
self.groups = Some(vec![name]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2515,12 +2570,12 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`ArgGroup`]: ./struct.ArgGroup.html
|
||||
pub fn groups(mut self, names: &[&'a str]) -> Self {
|
||||
if let Some(ref mut vec) = self.b.groups {
|
||||
if let Some(ref mut vec) = self.groups {
|
||||
for s in names {
|
||||
vec.push(s);
|
||||
}
|
||||
} else {
|
||||
self.b.groups = Some(names.into_iter().map(|s| *s).collect::<Vec<_>>());
|
||||
self.groups = Some(names.into_iter().map(|s| *s).collect::<Vec<_>>());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -2563,7 +2618,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
|
||||
pub fn number_of_values(mut self, qty: u64) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.v.num_vals = Some(qty);
|
||||
self.num_vals = Some(qty);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -2607,7 +2662,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
where
|
||||
F: Fn(String) -> Result<(), String> + 'static,
|
||||
{
|
||||
self.v.validator = Some(Rc::new(f));
|
||||
self.validator = Some(Rc::new(f));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -2645,7 +2700,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
where
|
||||
F: Fn(&OsStr) -> Result<(), OsString> + 'static,
|
||||
{
|
||||
self.v.validator_os = Some(Rc::new(f));
|
||||
self.validator_os = Some(Rc::new(f));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -2707,7 +2762,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
|
||||
pub fn max_values(mut self, qty: u64) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.v.max_vals = Some(qty);
|
||||
self.max_vals = Some(qty);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -2769,7 +2824,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// ```
|
||||
/// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
|
||||
pub fn min_values(mut self, qty: u64) -> Self {
|
||||
self.v.min_vals = Some(qty);
|
||||
self.min_vals = Some(qty);
|
||||
self.set(ArgSettings::TakesValue)
|
||||
}
|
||||
|
||||
|
@ -2821,14 +2876,14 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::value_delimiter`]: ./struct.Arg.html#method.value_delimiter
|
||||
pub fn use_delimiter(mut self, d: bool) -> Self {
|
||||
if d {
|
||||
if self.v.val_delim.is_none() {
|
||||
self.v.val_delim = Some(',');
|
||||
if self.val_delim.is_none() {
|
||||
self.val_delim = Some(',');
|
||||
}
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.setb(ArgSettings::UseValueDelimiter);
|
||||
self.unset(ArgSettings::ValueDelimiterNotSet)
|
||||
} else {
|
||||
self.v.val_delim = None;
|
||||
self.val_delim = None;
|
||||
self.unsetb(ArgSettings::UseValueDelimiter);
|
||||
self.unset(ArgSettings::ValueDelimiterNotSet)
|
||||
}
|
||||
|
@ -2946,7 +3001,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
self.unsetb(ArgSettings::ValueDelimiterNotSet);
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.setb(ArgSettings::UseValueDelimiter);
|
||||
self.v.val_delim = Some(
|
||||
self.val_delim = Some(
|
||||
d.chars()
|
||||
.nth(0)
|
||||
.expect("Failed to get value_delimiter from arg"),
|
||||
|
@ -3019,7 +3074,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
self.unsetb(ArgSettings::ValueDelimiterNotSet);
|
||||
self.setb(ArgSettings::UseValueDelimiter);
|
||||
}
|
||||
if let Some(ref mut vals) = self.v.val_names {
|
||||
if let Some(ref mut vals) = self.val_names {
|
||||
let mut l = vals.len();
|
||||
for s in names {
|
||||
vals.insert(l, s);
|
||||
|
@ -3030,7 +3085,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
for (i, n) in names.iter().enumerate() {
|
||||
vm.insert(i, *n);
|
||||
}
|
||||
self.v.val_names = Some(vm);
|
||||
self.val_names = Some(vm);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -3083,13 +3138,13 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
|
||||
pub fn value_name(mut self, name: &'b str) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
if let Some(ref mut vals) = self.v.val_names {
|
||||
if let Some(ref mut vals) = self.val_names {
|
||||
let l = vals.len();
|
||||
vals.insert(l, name);
|
||||
} else {
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, name);
|
||||
self.v.val_names = Some(vm);
|
||||
self.val_names = Some(vm);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -3167,7 +3222,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
|
||||
pub fn default_value_os(mut self, val: &'a OsStr) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
self.v.default_val = Some(val);
|
||||
self.default_val = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -3286,13 +3341,13 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
default: &'b OsStr,
|
||||
) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
if let Some(ref mut vm) = self.v.default_vals_ifs {
|
||||
if let Some(ref mut vm) = self.default_vals_ifs {
|
||||
let l = vm.len();
|
||||
vm.insert(l, (arg, val, default));
|
||||
} else {
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, (arg, val, default));
|
||||
self.v.default_vals_ifs = Some(vm);
|
||||
self.default_vals_ifs = Some(vm);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -3511,7 +3566,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
pub fn env_os(mut self, name: &'a OsStr) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
|
||||
self.v.env = Some((name, env::var_os(name)));
|
||||
self.env = Some((name, env::var_os(name)));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -3634,13 +3689,13 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// [positional arguments]: ./struct.Arg.html#method.index
|
||||
/// [index]: ./struct.Arg.html#method.index
|
||||
pub fn display_order(mut self, ord: usize) -> Self {
|
||||
self.s.disp_ord = ord;
|
||||
self.disp_ord = ord;
|
||||
self
|
||||
}
|
||||
|
||||
/// Checks if one of the [`ArgSettings`] settings is set for the argument
|
||||
/// [`ArgSettings`]: ./enum.ArgSettings.html
|
||||
pub fn is_set(&self, s: ArgSettings) -> bool { self.b.is_set(s) }
|
||||
pub fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
|
||||
|
||||
/// Sets one of the [`ArgSettings`] settings for the argument
|
||||
/// [`ArgSettings`]: ./enum.ArgSettings.html
|
||||
|
@ -3657,24 +3712,373 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn setb(&mut self, s: ArgSettings) { self.b.set(s); }
|
||||
pub fn _build(&mut self) {
|
||||
if self.index.is_some() || (self.short.is_none() && self.long.is_none()) {
|
||||
if self.max_vals.is_some() || self.min_vals.is_some()
|
||||
|| (self.num_vals.is_some() && self.num_vals.unwrap() > 1)
|
||||
{
|
||||
self.setb(ArgSettings::Multiple);
|
||||
}
|
||||
} else if self.is_set(ArgSettings::TakesValue) {
|
||||
if let Some(ref vec) = self.val_names {
|
||||
if vec.len() > 1 {
|
||||
self.num_vals = Some(vec.len() as u64);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn unsetb(&mut self, s: ArgSettings) { self.b.unset(s); }
|
||||
}
|
||||
pub fn setb(&mut self, s: ArgSettings) { self.settings.set(s); }
|
||||
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self {
|
||||
Arg {
|
||||
b: a.b.clone(),
|
||||
v: a.v.clone(),
|
||||
s: a.s.clone(),
|
||||
index: a.index,
|
||||
r_ifs: a.r_ifs.clone(),
|
||||
#[doc(hidden)]
|
||||
pub fn unsetb(&mut self, s: ArgSettings) { self.settings.unset(s); }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn has_switch(&self) -> bool { self.short.is_some() || self.long.is_some() }
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn longest_filter(&self) -> bool {
|
||||
self.is_set(ArgSettings::TakesValue) || self.long.is_some() || self.short.is_none()
|
||||
}
|
||||
|
||||
// Used for positionals when printing
|
||||
#[doc(hidden)]
|
||||
pub fn multiple_str(&self) -> &str {
|
||||
let mult_vals = self.val_names
|
||||
.as_ref()
|
||||
.map_or(true, |names| names.len() < 2);
|
||||
if self.is_set(ArgSettings::Multiple) && mult_vals {
|
||||
"..."
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
// Used for positionals when printing
|
||||
#[doc(hidden)]
|
||||
pub fn name_no_brackets(&self) -> Cow<str> {
|
||||
debugln!("PosBuilder::name_no_brackets:{}", self.name);
|
||||
let mut delim = String::new();
|
||||
delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
});
|
||||
if let Some(ref names) = self.val_names {
|
||||
debugln!("PosBuilder:name_no_brackets: val_names={:#?}", names);
|
||||
if names.len() > 1 {
|
||||
Cow::Owned(
|
||||
names
|
||||
.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(&*delim),
|
||||
)
|
||||
} else {
|
||||
Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG))
|
||||
}
|
||||
} else {
|
||||
debugln!("PosBuilder:name_no_brackets: just name");
|
||||
Cow::Borrowed(self.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for Arg<'n, 'e> {
|
||||
fn eq(&self, other: &Arg<'n, 'e>) -> bool { self.b == other.b }
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self { a.clone() }
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for Arg<'n, 'e> {
|
||||
fn eq(&self, other: &Arg<'n, 'e>) -> bool { self.name == other.name }
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for Arg<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if self.index.is_some() || (self.long.is_none() && self.short.is_none()) {
|
||||
// Positional
|
||||
let mut delim = String::new();
|
||||
delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
});
|
||||
if let Some(ref names) = self.val_names {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
names
|
||||
.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(&*delim)
|
||||
)?;
|
||||
} else {
|
||||
write!(f, "<{}>", self.name)?;
|
||||
}
|
||||
if self.settings.is_set(ArgSettings::Multiple)
|
||||
&& (self.val_names.is_none()
|
||||
|| (self.val_names.is_some()
|
||||
&& self.val_names.as_ref().unwrap().len() == 1))
|
||||
{
|
||||
write!(f, "...")?;
|
||||
}
|
||||
return Ok(());
|
||||
} else if !self.is_set(ArgSettings::TakesValue) {
|
||||
// Flag
|
||||
if let Some(l) = self.long {
|
||||
write!(f, "--{}", l)?;
|
||||
} else if let Some(s) = self.short {
|
||||
write!(f, "-{}", s)?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
let sep = if self.is_set(ArgSettings::RequireEquals) {
|
||||
"="
|
||||
} else {
|
||||
" "
|
||||
};
|
||||
// Write the name such --long or -l
|
||||
if let Some(l) = self.long {
|
||||
write!(f, "--{}{}", l, sep)?;
|
||||
} else {
|
||||
write!(f, "-{}{}", self.short.unwrap(), sep)?;
|
||||
}
|
||||
let delim = if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
};
|
||||
|
||||
// Write the values such as <name1> <name2>
|
||||
if let Some(ref vec) = self.val_names {
|
||||
let mut it = vec.iter().peekable();
|
||||
while let Some((_, val)) = it.next() {
|
||||
write!(f, "<{}>", val)?;
|
||||
if it.peek().is_some() {
|
||||
write!(f, "{}", delim)?;
|
||||
}
|
||||
}
|
||||
let num = vec.len();
|
||||
if self.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
} else if let Some(num) = self.num_vals {
|
||||
let mut it = (0..num).peekable();
|
||||
while let Some(_) = it.next() {
|
||||
write!(f, "<{}>", self.name)?;
|
||||
if it.peek().is_some() {
|
||||
write!(f, "{}", delim)?;
|
||||
}
|
||||
}
|
||||
if self.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"<{}>{}",
|
||||
self.name,
|
||||
if self.is_set(ArgSettings::Multiple) {
|
||||
"..."
|
||||
} else {
|
||||
""
|
||||
}
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialOrd for Arg<'n, 'e> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
|
||||
}
|
||||
|
||||
impl<'n, 'e> Ord for Arg<'n, 'e> {
|
||||
fn cmp(&self, other: &Arg) -> Ordering { self.name.cmp(&other.name) }
|
||||
}
|
||||
|
||||
impl<'n, 'e> Eq for Arg<'n, 'e> {}
|
||||
|
||||
impl<'n, 'e> fmt::Debug for Arg<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
write!(
|
||||
f,
|
||||
"Arg {{ name: {:?}, help: {:?}, long_help: {:?}, conflicts_with: {:?}, \
|
||||
settings: {:?}, required_unless: {:?}, overrides_with: {:?}, groups: {:?}, \
|
||||
requires: {:?}, requires_ifs: {:?}, short: {:?}, index: {:?}, long: {:?}, \
|
||||
aliases: {:?}, possible_values: {:?}, value_names: {:?}, number_of_values: {:?}, \
|
||||
max_values: {:?}, min_values: {:?}, value_delimiter: {:?}, default_value_ifs: {:?}, \
|
||||
value_terminator: {:?}, display_order: {:?}, env: {:?}, unified_ord: {:?}, \
|
||||
default_value: {:?}, validator: {}, validator_os: {} \
|
||||
}}",
|
||||
self.name,
|
||||
self.help,
|
||||
self.long_help,
|
||||
self.blacklist,
|
||||
self.settings,
|
||||
self.r_unless,
|
||||
self.overrides,
|
||||
self.groups,
|
||||
self.requires,
|
||||
self.r_ifs,
|
||||
self.short,
|
||||
self.index,
|
||||
self.long,
|
||||
self.aliases,
|
||||
self.possible_vals,
|
||||
self.val_names,
|
||||
self.num_vals,
|
||||
self.max_vals,
|
||||
self.min_vals,
|
||||
self.val_delim,
|
||||
self.default_vals_ifs,
|
||||
self.terminator,
|
||||
self.disp_ord,
|
||||
self.env,
|
||||
self.unified_ord,
|
||||
self.default_val,
|
||||
self.validator.as_ref().map_or("None", |_| "Some(Fn)"),
|
||||
self.validator_os.as_ref().map_or("None", |_| "Some(Fn)")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Flags
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use map::VecMap;
|
||||
use args::settings::ArgSettings;
|
||||
use super::Arg;
|
||||
|
||||
#[test]
|
||||
fn flag_display() {
|
||||
let mut f = Arg::with_name("flg");
|
||||
f.settings.set(ArgSettings::Multiple);
|
||||
f.long = Some("flag");
|
||||
|
||||
assert_eq!(&*format!("{}", f), "--flag");
|
||||
|
||||
let mut f2 = Arg::with_name("flg");
|
||||
f2.short = Some('f');
|
||||
|
||||
assert_eq!(&*format!("{}", f2), "-f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_display_single_alias() {
|
||||
let mut f = Arg::with_name("flg");
|
||||
f.long = Some("flag");
|
||||
f.aliases = Some(vec![("als", true)]);
|
||||
|
||||
assert_eq!(&*format!("{}", f), "--flag");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_display_multiple_aliases() {
|
||||
let mut f = Arg::with_name("flg");
|
||||
f.short = Some('f');
|
||||
f.aliases = Some(vec![
|
||||
("alias_not_visible", false),
|
||||
("f2", true),
|
||||
("f3", true),
|
||||
("f4", true),
|
||||
]);
|
||||
assert_eq!(&*format!("{}", f), "-f");
|
||||
}
|
||||
|
||||
// Options
|
||||
|
||||
#[test]
|
||||
fn option_display1() {
|
||||
let o = Arg::with_name("opt")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.multiple(true);
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_display2() {
|
||||
let o2 = Arg::with_name("opt")
|
||||
.short("o")
|
||||
.value_names(&["file", "name"]);
|
||||
|
||||
assert_eq!(&*format!("{}", o2), "-o <file> <name>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_display3() {
|
||||
let o2 = Arg::with_name("opt")
|
||||
.short("o")
|
||||
.multiple(true)
|
||||
.value_names(&["file", "name"]);
|
||||
|
||||
assert_eq!(&*format!("{}", o2), "-o <file> <name>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_display_single_alias() {
|
||||
let o = Arg::with_name("opt")
|
||||
.takes_value(true)
|
||||
.long("option")
|
||||
.visible_alias("als");
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_display_multiple_aliases() {
|
||||
let o = Arg::with_name("opt")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.visible_aliases(&["als2", "als3", "als4"])
|
||||
.alias("als_not_visible");
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>");
|
||||
}
|
||||
|
||||
// Positionals
|
||||
|
||||
#[test]
|
||||
fn positiona_display_mult() {
|
||||
let mut p = Arg::with_name("pos").index(1);
|
||||
p.settings.set(ArgSettings::Multiple);
|
||||
|
||||
assert_eq!(&*format!("{}", p), "<pos>...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_display_required() {
|
||||
let mut p2 = Arg::with_name("pos").index(1);
|
||||
p2.settings.set(ArgSettings::Required);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<pos>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_display_val_names() {
|
||||
let mut p2 = Arg::with_name("pos").index(1);
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, "file1");
|
||||
vm.insert(1, "file2");
|
||||
p2.val_names = Some(vm);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<file1> <file2>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn positional_display_val_names_req() {
|
||||
let mut p2 = Arg::with_name("pos").index(1);
|
||||
p2.settings.set(ArgSettings::Required);
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, "file1");
|
||||
vm.insert(1, "file2");
|
||||
p2.val_names = Some(vm);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<file1> <file2>");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
use args::{Arg, ArgFlags, ArgSettings};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Base<'a, 'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
pub name: &'a str,
|
||||
pub help: Option<&'b str>,
|
||||
pub long_help: Option<&'b str>,
|
||||
pub blacklist: Option<Vec<&'a str>>,
|
||||
pub settings: ArgFlags,
|
||||
pub r_unless: Option<Vec<&'a str>>,
|
||||
pub overrides: Option<Vec<&'a str>>,
|
||||
pub groups: Option<Vec<&'a str>>,
|
||||
pub requires: Option<Vec<(Option<&'b str>, &'a str)>>,
|
||||
}
|
||||
|
||||
impl<'n, 'e> Base<'n, 'e> {
|
||||
pub fn new(name: &'n str) -> Self {
|
||||
Base {
|
||||
name: name,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, s: ArgSettings) { self.settings.set(s); }
|
||||
pub fn unset(&mut self, s: ArgSettings) { self.settings.unset(s); }
|
||||
pub fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
|
||||
}
|
||||
|
||||
impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Base<'n, 'e> {
|
||||
fn from(a: &'z Arg<'n, 'e>) -> Self { a.b.clone() }
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for Base<'n, 'e> {
|
||||
fn eq(&self, other: &Base<'n, 'e>) -> bool { self.name == other.name }
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
// Std
|
||||
use std::convert::From;
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
use std::rc::Rc;
|
||||
use std::result::Result as StdResult;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::mem;
|
||||
|
||||
// Internal
|
||||
use Arg;
|
||||
use args::{AnyArg, ArgSettings, Base, DispOrder, Switched};
|
||||
use map::{self, VecMap};
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
#[doc(hidden)]
|
||||
pub struct FlagBuilder<'n, 'e>
|
||||
where
|
||||
'n: 'e,
|
||||
{
|
||||
pub b: Base<'n, 'e>,
|
||||
pub s: Switched<'e>,
|
||||
}
|
||||
|
||||
impl<'n, 'e> FlagBuilder<'n, 'e> {
|
||||
pub fn new(name: &'n str) -> Self {
|
||||
FlagBuilder {
|
||||
b: Base::new(name),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self {
|
||||
FlagBuilder {
|
||||
b: Base::from(a),
|
||||
s: Switched::from(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> From<Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
|
||||
fn from(mut a: Arg<'a, 'b>) -> Self {
|
||||
FlagBuilder {
|
||||
b: mem::replace(&mut a.b, Base::default()),
|
||||
s: mem::replace(&mut a.s, Switched::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for FlagBuilder<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
if let Some(l) = self.s.long {
|
||||
write!(f, "--{}", l)?;
|
||||
} else {
|
||||
write!(f, "-{}", self.s.short.unwrap())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.b.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
|
||||
self.b.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
|
||||
fn has_switch(&self) -> bool { true }
|
||||
fn takes_value(&self) -> bool { false }
|
||||
fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
|
||||
fn max_vals(&self) -> Option<u64> { None }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
|
||||
fn num_vals(&self) -> Option<u64> { None }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { None }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
|
||||
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
|
||||
fn min_vals(&self) -> Option<u64> { None }
|
||||
fn short(&self) -> Option<char> { self.s.short }
|
||||
fn long(&self) -> Option<&'e str> { self.s.long }
|
||||
fn val_delim(&self) -> Option<char> { None }
|
||||
fn help(&self) -> Option<&'e str> { self.b.help }
|
||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||
fn val_terminator(&self) -> Option<&'e str> { None }
|
||||
fn default_val(&self) -> Option<&'e OsStr> { None }
|
||||
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||
None
|
||||
}
|
||||
fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { None }
|
||||
fn longest_filter(&self) -> bool { self.s.long.is_some() }
|
||||
fn aliases(&self) -> Option<Vec<&'e str>> {
|
||||
if let Some(ref aliases) = self.s.aliases {
|
||||
let vis_aliases: Vec<_> = aliases
|
||||
.iter()
|
||||
.filter_map(|&(n, v)| if v { Some(n) } else { None })
|
||||
.collect();
|
||||
if vis_aliases.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(vis_aliases)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.s.disp_ord }
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> {
|
||||
fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool { self.b == other.b }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use args::settings::ArgSettings;
|
||||
use super::FlagBuilder;
|
||||
|
||||
#[test]
|
||||
fn flagbuilder_display() {
|
||||
let mut f = FlagBuilder::new("flg");
|
||||
f.b.settings.set(ArgSettings::Multiple);
|
||||
f.s.long = Some("flag");
|
||||
|
||||
assert_eq!(&*format!("{}", f), "--flag");
|
||||
|
||||
let mut f2 = FlagBuilder::new("flg");
|
||||
f2.s.short = Some('f');
|
||||
|
||||
assert_eq!(&*format!("{}", f2), "-f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flagbuilder_display_single_alias() {
|
||||
let mut f = FlagBuilder::new("flg");
|
||||
f.s.long = Some("flag");
|
||||
f.s.aliases = Some(vec![("als", true)]);
|
||||
|
||||
assert_eq!(&*format!("{}", f), "--flag");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flagbuilder_display_multiple_aliases() {
|
||||
let mut f = FlagBuilder::new("flg");
|
||||
f.s.short = Some('f');
|
||||
f.s.aliases = Some(vec![
|
||||
("alias_not_visible", false),
|
||||
("f2", true),
|
||||
("f3", true),
|
||||
("f4", true),
|
||||
]);
|
||||
assert_eq!(&*format!("{}", f), "-f");
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
pub use self::flag::FlagBuilder;
|
||||
pub use self::option::OptBuilder;
|
||||
pub use self::positional::PosBuilder;
|
||||
pub use self::base::Base;
|
||||
pub use self::switched::Switched;
|
||||
pub use self::valued::Valued;
|
||||
|
||||
mod flag;
|
||||
mod positional;
|
||||
mod option;
|
||||
mod base;
|
||||
mod valued;
|
||||
mod switched;
|
|
@ -1,244 +0,0 @@
|
|||
// Std
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
use std::rc::Rc;
|
||||
use std::result::Result as StdResult;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::mem;
|
||||
|
||||
// Internal
|
||||
use args::{AnyArg, Arg, ArgSettings, Base, DispOrder, Switched, Valued};
|
||||
use map::{self, VecMap};
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[doc(hidden)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct OptBuilder<'n, 'e>
|
||||
where
|
||||
'n: 'e,
|
||||
{
|
||||
pub b: Base<'n, 'e>,
|
||||
pub s: Switched<'e>,
|
||||
pub v: Valued<'n, 'e>,
|
||||
}
|
||||
|
||||
impl<'n, 'e> OptBuilder<'n, 'e> {
|
||||
pub fn new(name: &'n str) -> Self {
|
||||
OptBuilder {
|
||||
b: Base::new(name),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for OptBuilder<'n, 'e> {
|
||||
fn from(a: &'z Arg<'n, 'e>) -> Self {
|
||||
OptBuilder {
|
||||
b: Base::from(a),
|
||||
s: Switched::from(a),
|
||||
v: Valued::from(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> From<Arg<'n, 'e>> for OptBuilder<'n, 'e> {
|
||||
fn from(mut a: Arg<'n, 'e>) -> Self {
|
||||
a.v.fill_in();
|
||||
OptBuilder {
|
||||
b: mem::replace(&mut a.b, Base::default()),
|
||||
s: mem::replace(&mut a.s, Switched::default()),
|
||||
v: mem::replace(&mut a.v, Valued::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for OptBuilder<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
debugln!("OptBuilder::fmt:{}", self.b.name);
|
||||
let sep = if self.b.is_set(ArgSettings::RequireEquals) {
|
||||
"="
|
||||
} else {
|
||||
" "
|
||||
};
|
||||
// Write the name such --long or -l
|
||||
if let Some(l) = self.s.long {
|
||||
write!(f, "--{}{}", l, sep)?;
|
||||
} else {
|
||||
write!(f, "-{}{}", self.s.short.unwrap(), sep)?;
|
||||
}
|
||||
let delim = if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.v.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
};
|
||||
|
||||
// Write the values such as <name1> <name2>
|
||||
if let Some(ref vec) = self.v.val_names {
|
||||
let mut it = vec.iter().peekable();
|
||||
while let Some((_, val)) = it.next() {
|
||||
write!(f, "<{}>", val)?;
|
||||
if it.peek().is_some() {
|
||||
write!(f, "{}", delim)?;
|
||||
}
|
||||
}
|
||||
let num = vec.len();
|
||||
if self.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
} else if let Some(num) = self.v.num_vals {
|
||||
let mut it = (0..num).peekable();
|
||||
while let Some(_) = it.next() {
|
||||
write!(f, "<{}>", self.b.name)?;
|
||||
if it.peek().is_some() {
|
||||
write!(f, "{}", delim)?;
|
||||
}
|
||||
}
|
||||
if self.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"<{}>{}",
|
||||
self.b.name,
|
||||
if self.is_set(ArgSettings::Multiple) {
|
||||
"..."
|
||||
} else {
|
||||
""
|
||||
}
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.b.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
|
||||
self.b.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { self.v.val_names.as_ref() }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
|
||||
fn has_switch(&self) -> bool { true }
|
||||
fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
|
||||
fn max_vals(&self) -> Option<u64> { self.v.max_vals }
|
||||
fn val_terminator(&self) -> Option<&'e str> { self.v.terminator }
|
||||
fn num_vals(&self) -> Option<u64> { self.v.num_vals }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { self.v.possible_vals.as_ref().map(|o| &o[..]) }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
self.v.validator.as_ref()
|
||||
}
|
||||
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
|
||||
self.v.validator_os.as_ref()
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> { self.v.min_vals }
|
||||
fn short(&self) -> Option<char> { self.s.short }
|
||||
fn long(&self) -> Option<&'e str> { self.s.long }
|
||||
fn val_delim(&self) -> Option<char> { self.v.val_delim }
|
||||
fn takes_value(&self) -> bool { true }
|
||||
fn help(&self) -> Option<&'e str> { self.b.help }
|
||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
||||
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
||||
}
|
||||
fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
|
||||
self.v
|
||||
.env
|
||||
.as_ref()
|
||||
.map(|&(key, ref value)| (key, value.as_ref()))
|
||||
}
|
||||
fn longest_filter(&self) -> bool { true }
|
||||
fn aliases(&self) -> Option<Vec<&'e str>> {
|
||||
if let Some(ref aliases) = self.s.aliases {
|
||||
let vis_aliases: Vec<_> = aliases
|
||||
.iter()
|
||||
.filter_map(|&(n, v)| if v { Some(n) } else { None })
|
||||
.collect();
|
||||
if vis_aliases.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(vis_aliases)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.s.disp_ord }
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for OptBuilder<'n, 'e> {
|
||||
fn eq(&self, other: &OptBuilder<'n, 'e>) -> bool { self.b == other.b }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use args::settings::ArgSettings;
|
||||
use super::OptBuilder;
|
||||
use map::VecMap;
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display1() {
|
||||
let mut o = OptBuilder::new("opt");
|
||||
o.s.long = Some("option");
|
||||
o.b.settings.set(ArgSettings::Multiple);
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display2() {
|
||||
let mut v_names = VecMap::new();
|
||||
v_names.insert(0, "file");
|
||||
v_names.insert(1, "name");
|
||||
|
||||
let mut o2 = OptBuilder::new("opt");
|
||||
o2.s.short = Some('o');
|
||||
o2.v.val_names = Some(v_names);
|
||||
|
||||
assert_eq!(&*format!("{}", o2), "-o <file> <name>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display3() {
|
||||
let mut v_names = VecMap::new();
|
||||
v_names.insert(0, "file");
|
||||
v_names.insert(1, "name");
|
||||
|
||||
let mut o2 = OptBuilder::new("opt");
|
||||
o2.s.short = Some('o');
|
||||
o2.v.val_names = Some(v_names);
|
||||
o2.b.settings.set(ArgSettings::Multiple);
|
||||
|
||||
assert_eq!(&*format!("{}", o2), "-o <file> <name>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display_single_alias() {
|
||||
let mut o = OptBuilder::new("opt");
|
||||
o.s.long = Some("option");
|
||||
o.s.aliases = Some(vec![("als", true)]);
|
||||
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optbuilder_display_multiple_aliases() {
|
||||
let mut o = OptBuilder::new("opt");
|
||||
o.s.long = Some("option");
|
||||
o.s.aliases = Some(vec![
|
||||
("als_not_visible", false),
|
||||
("als2", true),
|
||||
("als3", true),
|
||||
("als4", true),
|
||||
]);
|
||||
assert_eq!(&*format!("{}", o), "--option <opt>");
|
||||
}
|
||||
}
|
|
@ -1,229 +0,0 @@
|
|||
// Std
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
use std::rc::Rc;
|
||||
use std::result::Result as StdResult;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::mem;
|
||||
|
||||
// Internal
|
||||
use Arg;
|
||||
use args::{AnyArg, ArgSettings, Base, DispOrder, Valued};
|
||||
use INTERNAL_ERROR_MSG;
|
||||
use map::{self, VecMap};
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct PosBuilder<'n, 'e>
|
||||
where
|
||||
'n: 'e,
|
||||
{
|
||||
pub b: Base<'n, 'e>,
|
||||
pub v: Valued<'n, 'e>,
|
||||
pub index: u64,
|
||||
}
|
||||
|
||||
impl<'n, 'e> PosBuilder<'n, 'e> {
|
||||
pub fn new(name: &'n str, idx: u64) -> Self {
|
||||
PosBuilder {
|
||||
b: Base::new(name),
|
||||
index: idx,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_arg_ref(a: &Arg<'n, 'e>, idx: u64) -> Self {
|
||||
let mut pb = PosBuilder {
|
||||
b: Base::from(a),
|
||||
v: Valued::from(a),
|
||||
index: idx,
|
||||
};
|
||||
if a.v.max_vals.is_some() || a.v.min_vals.is_some()
|
||||
|| (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
|
||||
{
|
||||
pb.b.settings.set(ArgSettings::Multiple);
|
||||
}
|
||||
pb
|
||||
}
|
||||
|
||||
pub fn from_arg(mut a: Arg<'n, 'e>, idx: u64) -> Self {
|
||||
if a.v.max_vals.is_some() || a.v.min_vals.is_some()
|
||||
|| (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
|
||||
{
|
||||
a.b.settings.set(ArgSettings::Multiple);
|
||||
}
|
||||
PosBuilder {
|
||||
b: mem::replace(&mut a.b, Base::default()),
|
||||
v: mem::replace(&mut a.v, Valued::default()),
|
||||
index: idx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn multiple_str(&self) -> &str {
|
||||
let mult_vals = self.v
|
||||
.val_names
|
||||
.as_ref()
|
||||
.map_or(true, |names| names.len() < 2);
|
||||
if self.is_set(ArgSettings::Multiple) && mult_vals {
|
||||
"..."
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name_no_brackets(&self) -> Cow<str> {
|
||||
debugln!("PosBuilder::name_no_brackets;");
|
||||
let mut delim = String::new();
|
||||
delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.v.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
});
|
||||
if let Some(ref names) = self.v.val_names {
|
||||
debugln!("PosBuilder:name_no_brackets: val_names={:#?}", names);
|
||||
if names.len() > 1 {
|
||||
Cow::Owned(
|
||||
names
|
||||
.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(&*delim),
|
||||
)
|
||||
} else {
|
||||
Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG))
|
||||
}
|
||||
} else {
|
||||
debugln!("PosBuilder:name_no_brackets: just name");
|
||||
Cow::Borrowed(self.b.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for PosBuilder<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
let mut delim = String::new();
|
||||
delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
|
||||
self.v.val_delim.expect(INTERNAL_ERROR_MSG)
|
||||
} else {
|
||||
' '
|
||||
});
|
||||
if let Some(ref names) = self.v.val_names {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
names
|
||||
.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(&*delim)
|
||||
)?;
|
||||
} else {
|
||||
write!(f, "<{}>", self.b.name)?;
|
||||
}
|
||||
if self.b.settings.is_set(ArgSettings::Multiple)
|
||||
&& (self.v.val_names.is_none() || self.v.val_names.as_ref().unwrap().len() == 1)
|
||||
{
|
||||
write!(f, "...")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.b.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
|
||||
self.b.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { self.v.val_names.as_ref() }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
|
||||
fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
|
||||
fn has_switch(&self) -> bool { false }
|
||||
fn max_vals(&self) -> Option<u64> { self.v.max_vals }
|
||||
fn val_terminator(&self) -> Option<&'e str> { self.v.terminator }
|
||||
fn num_vals(&self) -> Option<u64> { self.v.num_vals }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { self.v.possible_vals.as_ref().map(|o| &o[..]) }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
self.v.validator.as_ref()
|
||||
}
|
||||
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
|
||||
self.v.validator_os.as_ref()
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> { self.v.min_vals }
|
||||
fn short(&self) -> Option<char> { None }
|
||||
fn long(&self) -> Option<&'e str> { None }
|
||||
fn val_delim(&self) -> Option<char> { self.v.val_delim }
|
||||
fn takes_value(&self) -> bool { true }
|
||||
fn help(&self) -> Option<&'e str> { self.b.help }
|
||||
fn long_help(&self) -> Option<&'e str> { self.b.long_help }
|
||||
fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
|
||||
self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
|
||||
}
|
||||
fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
|
||||
fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
|
||||
self.v
|
||||
.env
|
||||
.as_ref()
|
||||
.map(|&(key, ref value)| (key, value.as_ref()))
|
||||
}
|
||||
fn longest_filter(&self) -> bool { true }
|
||||
fn aliases(&self) -> Option<Vec<&'e str>> { None }
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.index as usize }
|
||||
}
|
||||
|
||||
impl<'n, 'e> PartialEq for PosBuilder<'n, 'e> {
|
||||
fn eq(&self, other: &PosBuilder<'n, 'e>) -> bool { self.b == other.b }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use args::settings::ArgSettings;
|
||||
use super::PosBuilder;
|
||||
use map::VecMap;
|
||||
|
||||
#[test]
|
||||
fn display_mult() {
|
||||
let mut p = PosBuilder::new("pos", 1);
|
||||
p.b.settings.set(ArgSettings::Multiple);
|
||||
|
||||
assert_eq!(&*format!("{}", p), "<pos>...");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_required() {
|
||||
let mut p2 = PosBuilder::new("pos", 1);
|
||||
p2.b.settings.set(ArgSettings::Required);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<pos>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_val_names() {
|
||||
let mut p2 = PosBuilder::new("pos", 1);
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, "file1");
|
||||
vm.insert(1, "file2");
|
||||
p2.v.val_names = Some(vm);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<file1> <file2>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_val_names_req() {
|
||||
let mut p2 = PosBuilder::new("pos", 1);
|
||||
p2.b.settings.set(ArgSettings::Required);
|
||||
let mut vm = VecMap::new();
|
||||
vm.insert(0, "file1");
|
||||
vm.insert(1, "file2");
|
||||
p2.v.val_names = Some(vm);
|
||||
|
||||
assert_eq!(&*format!("{}", p2), "<file1> <file2>");
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
use Arg;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Switched<'b> {
|
||||
pub short: Option<char>,
|
||||
pub long: Option<&'b str>,
|
||||
pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
|
||||
pub disp_ord: usize,
|
||||
pub unified_ord: usize,
|
||||
}
|
||||
|
||||
impl<'e> Default for Switched<'e> {
|
||||
fn default() -> Self {
|
||||
Switched {
|
||||
short: None,
|
||||
long: None,
|
||||
aliases: None,
|
||||
disp_ord: 999,
|
||||
unified_ord: 999,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Switched<'e> {
|
||||
fn from(a: &'z Arg<'n, 'e>) -> Self { a.s.clone() }
|
||||
}
|
||||
|
||||
impl<'e> Clone for Switched<'e> {
|
||||
fn clone(&self) -> Self {
|
||||
Switched {
|
||||
short: self.short,
|
||||
long: self.long,
|
||||
aliases: self.aliases.clone(),
|
||||
disp_ord: self.disp_ord,
|
||||
unified_ord: self.unified_ord,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
use std::rc::Rc;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
|
||||
use map::VecMap;
|
||||
|
||||
use Arg;
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[derive(Clone)]
|
||||
pub struct Valued<'a, 'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
pub possible_vals: Option<Vec<&'b str>>,
|
||||
pub val_names: Option<VecMap<&'b str>>,
|
||||
pub num_vals: Option<u64>,
|
||||
pub max_vals: Option<u64>,
|
||||
pub min_vals: Option<u64>,
|
||||
pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
|
||||
pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
|
||||
pub val_delim: Option<char>,
|
||||
pub default_val: Option<&'b OsStr>,
|
||||
pub default_vals_ifs: Option<VecMap<(&'a str, Option<&'b OsStr>, &'b OsStr)>>,
|
||||
pub env: Option<(&'a OsStr, Option<OsString>)>,
|
||||
pub terminator: Option<&'b str>,
|
||||
}
|
||||
|
||||
impl<'n, 'e> Default for Valued<'n, 'e> {
|
||||
fn default() -> Self {
|
||||
Valued {
|
||||
possible_vals: None,
|
||||
num_vals: None,
|
||||
min_vals: None,
|
||||
max_vals: None,
|
||||
val_names: None,
|
||||
validator: None,
|
||||
validator_os: None,
|
||||
val_delim: None,
|
||||
default_val: None,
|
||||
default_vals_ifs: None,
|
||||
env: None,
|
||||
terminator: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> Valued<'n, 'e> {
|
||||
pub fn fill_in(&mut self) {
|
||||
if let Some(ref vec) = self.val_names {
|
||||
if vec.len() > 1 {
|
||||
self.num_vals = Some(vec.len() as u64);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Valued<'n, 'e> {
|
||||
fn from(a: &'z Arg<'n, 'e>) -> Self {
|
||||
let mut v = a.v.clone();
|
||||
if let Some(ref vec) = a.v.val_names {
|
||||
if vec.len() > 1 {
|
||||
v.num_vals = Some(vec.len() as u64);
|
||||
}
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
// Std
|
||||
use std::collections::hash_map::{Entry, Iter};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::ops::Deref;
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
|
||||
// Third Party
|
||||
use ordermap;
|
||||
|
||||
// Internal
|
||||
use args::{ArgMatches, MatchedArg, SubCommand};
|
||||
use args::AnyArg;
|
||||
use args::{Arg, ArgMatches, MatchedArg, SubCommand};
|
||||
use args::settings::ArgSettings;
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -21,36 +21,13 @@ impl<'a> Default for ArgMatcher<'a> {
|
|||
impl<'a> ArgMatcher<'a> {
|
||||
pub fn new() -> Self { ArgMatcher::default() }
|
||||
|
||||
pub fn process_arg_overrides<'b>(&mut self, a: Option<&AnyArg<'a, 'b>>, overrides: &mut Vec<(&'b str, &'a str)>, required: &mut Vec<&'a str>) {
|
||||
debugln!("ArgMatcher::process_arg_overrides:{:?};", a.map_or(None, |a| Some(a.name())));
|
||||
if let Some(aa) = a {
|
||||
if let Some(a_overrides) = aa.overrides() {
|
||||
for overr in a_overrides {
|
||||
debugln!("ArgMatcher::process_arg_overrides:iter:{};", overr);
|
||||
if self.is_present(overr) {
|
||||
debugln!("ArgMatcher::process_arg_overrides:iter:{}: removing from matches;", overr);
|
||||
self.remove(overr);
|
||||
for i in (0 .. required.len()).rev() {
|
||||
if &required[i] == overr {
|
||||
debugln!("ArgMatcher::process_arg_overrides:iter:{}: removing required;", overr);
|
||||
required.swap_remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
overrides.push((overr, aa.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_present(&self, name: &str) -> bool {
|
||||
self.0.is_present(name)
|
||||
}
|
||||
pub fn is_present(&self, name: &str) -> bool { self.0.is_present(name) }
|
||||
|
||||
pub fn propagate_globals(&mut self, global_arg_vec: &[&'a str]) {
|
||||
debugln!( "ArgMatcher::get_global_values: global_arg_vec={:?}", global_arg_vec );
|
||||
debugln!(
|
||||
"ArgMatcher::get_global_values: global_arg_vec={:?}",
|
||||
global_arg_vec
|
||||
);
|
||||
let mut vals_map = HashMap::new();
|
||||
self.fill_in_global_values(global_arg_vec, &mut vals_map);
|
||||
}
|
||||
|
@ -97,6 +74,7 @@ impl<'a> ArgMatcher<'a> {
|
|||
|
||||
pub fn remove(&mut self, arg: &str) { self.0.args.remove(arg); }
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn remove_all(&mut self, args: &[&str]) {
|
||||
for &arg in args {
|
||||
self.0.args.remove(arg);
|
||||
|
@ -111,15 +89,17 @@ impl<'a> ArgMatcher<'a> {
|
|||
|
||||
pub fn usage(&mut self, usage: String) { self.0.usage = Some(usage); }
|
||||
|
||||
pub fn arg_names(&'a self) -> Vec<&'a str> { self.0.args.keys().map(Deref::deref).collect() }
|
||||
pub fn arg_names(&'a self) -> ordermap::Keys<&'a str, MatchedArg> { self.0.args.keys() }
|
||||
|
||||
pub fn entry(&mut self, arg: &'a str) -> Entry<&'a str, MatchedArg> { self.0.args.entry(arg) }
|
||||
pub fn entry(&mut self, arg: &'a str) -> ordermap::Entry<&'a str, MatchedArg> {
|
||||
self.0.args.entry(arg)
|
||||
}
|
||||
|
||||
pub fn subcommand(&mut self, sc: SubCommand<'a>) { self.0.subcommand = Some(Box::new(sc)); }
|
||||
|
||||
pub fn subcommand_name(&self) -> Option<&str> { self.0.subcommand_name() }
|
||||
|
||||
pub fn iter(&self) -> Iter<&str, MatchedArg> { self.0.args.iter() }
|
||||
pub fn iter(&self) -> ordermap::Iter<&str, MatchedArg> { self.0.args.iter() }
|
||||
|
||||
pub fn inc_occurrence_of(&mut self, arg: &'a str) {
|
||||
debugln!("ArgMatcher::inc_occurrence_of: arg={}", arg);
|
||||
|
@ -147,23 +127,20 @@ impl<'a> ArgMatcher<'a> {
|
|||
ma.vals.push(val.to_owned());
|
||||
}
|
||||
|
||||
pub fn needs_more_vals<'b, A>(&self, o: &A) -> bool
|
||||
where
|
||||
A: AnyArg<'a, 'b>,
|
||||
{
|
||||
debugln!("ArgMatcher::needs_more_vals: o={}", o.name());
|
||||
if let Some(ma) = self.get(o.name()) {
|
||||
if let Some(num) = o.num_vals() {
|
||||
pub fn needs_more_vals<'b>(&self, o: &Arg) -> bool {
|
||||
debugln!("ArgMatcher::needs_more_vals: o={}", o.name);
|
||||
if let Some(ma) = self.get(o.name) {
|
||||
if let Some(num) = o.num_vals {
|
||||
debugln!("ArgMatcher::needs_more_vals: num_vals...{}", num);
|
||||
return if o.is_set(ArgSettings::Multiple) {
|
||||
((ma.vals.len() as u64) % num) != 0
|
||||
} else {
|
||||
num != (ma.vals.len() as u64)
|
||||
};
|
||||
} else if let Some(num) = o.max_vals() {
|
||||
} else if let Some(num) = o.max_vals {
|
||||
debugln!("ArgMatcher::needs_more_vals: max_vals...{}", num);
|
||||
return !((ma.vals.len() as u64) > num);
|
||||
} else if o.min_vals().is_some() {
|
||||
} else if o.min_vals.is_some() {
|
||||
debugln!("ArgMatcher::needs_more_vals: min_vals...true");
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// Std
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::iter::Map;
|
||||
use std::slice::Iter;
|
||||
|
||||
// Third Party
|
||||
use ordermap::OrderMap;
|
||||
|
||||
// Internal
|
||||
use INVALID_UTF8;
|
||||
use args::MatchedArg;
|
||||
|
@ -59,15 +61,18 @@ use args::SubCommand;
|
|||
/// [`App::get_matches`]: ./struct.App.html#method.get_matches
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArgMatches<'a> {
|
||||
#[doc(hidden)] pub args: HashMap<&'a str, MatchedArg>,
|
||||
#[doc(hidden)] pub subcommand: Option<Box<SubCommand<'a>>>,
|
||||
#[doc(hidden)] pub usage: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub args: OrderMap<&'a str, MatchedArg>,
|
||||
#[doc(hidden)]
|
||||
pub subcommand: Option<Box<SubCommand<'a>>>,
|
||||
#[doc(hidden)]
|
||||
pub usage: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> Default for ArgMatches<'a> {
|
||||
fn default() -> Self {
|
||||
ArgMatches {
|
||||
args: HashMap::new(),
|
||||
args: OrderMap::new(),
|
||||
subcommand: None,
|
||||
usage: None,
|
||||
}
|
||||
|
@ -536,7 +541,6 @@ impl<'a> ArgMatches<'a> {
|
|||
pub fn usage(&self) -> &str { self.usage.as_ref().map_or("", |u| &u[..]) }
|
||||
}
|
||||
|
||||
|
||||
// The following were taken and adapated from vec_map source
|
||||
// repo: https://github.com/contain-rs/vec-map
|
||||
// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
|
||||
|
|
|
@ -79,12 +79,18 @@ use yaml_rust::Yaml;
|
|||
/// [requirement]: ./struct.Arg.html#method.requires
|
||||
#[derive(Default)]
|
||||
pub struct ArgGroup<'a> {
|
||||
#[doc(hidden)] pub name: &'a str,
|
||||
#[doc(hidden)] pub args: Vec<&'a str>,
|
||||
#[doc(hidden)] pub required: bool,
|
||||
#[doc(hidden)] pub requires: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)] pub conflicts: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)] pub multiple: bool,
|
||||
#[doc(hidden)]
|
||||
pub name: &'a str,
|
||||
#[doc(hidden)]
|
||||
pub args: Vec<&'a str>,
|
||||
#[doc(hidden)]
|
||||
pub required: bool,
|
||||
#[doc(hidden)]
|
||||
pub requires: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub conflicts: Option<Vec<&'a str>>,
|
||||
#[doc(hidden)]
|
||||
pub multiple: bool,
|
||||
}
|
||||
|
||||
impl<'a> ArgGroup<'a> {
|
||||
|
@ -431,11 +437,7 @@ impl<'a> Debug for ArgGroup<'a> {
|
|||
\trequires: {:?},\n\
|
||||
\tconflicts: {:?},\n\
|
||||
}}",
|
||||
self.name,
|
||||
self.args,
|
||||
self.required,
|
||||
self.requires,
|
||||
self.conflicts
|
||||
self.name, self.args, self.required, self.requires, self.conflicts
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -494,8 +496,7 @@ impl<'a> From<&'a BTreeMap<Yaml, Yaml>> for ArgGroup<'a> {
|
|||
s => panic!(
|
||||
"Unknown ArgGroup setting '{}' in YAML file for \
|
||||
ArgGroup '{}'",
|
||||
s,
|
||||
a.name
|
||||
s, a.name
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@ use std::ffi::OsString;
|
|||
#[doc(hidden)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MatchedArg {
|
||||
#[doc(hidden)] pub occurs: u64,
|
||||
#[doc(hidden)] pub vals: Vec<OsString>,
|
||||
#[doc(hidden)]
|
||||
pub occurs: u64,
|
||||
#[doc(hidden)]
|
||||
pub vals: Vec<OsString>,
|
||||
}
|
||||
|
||||
impl Default for MatchedArg {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
pub use self::any_arg::{AnyArg, DispOrder};
|
||||
pub use self::arg::Arg;
|
||||
pub use self::arg_builder::{Base, FlagBuilder, OptBuilder, PosBuilder, Switched, Valued};
|
||||
pub use self::arg_matcher::ArgMatcher;
|
||||
pub use self::arg_matches::{ArgMatches, OsValues, Values};
|
||||
pub use self::group::ArgGroup;
|
||||
|
@ -11,11 +9,9 @@ pub use self::subcommand::SubCommand;
|
|||
#[macro_use]
|
||||
mod macros;
|
||||
mod arg;
|
||||
pub mod any_arg;
|
||||
mod arg_matches;
|
||||
mod arg_matcher;
|
||||
mod subcommand;
|
||||
mod arg_builder;
|
||||
mod matched_arg;
|
||||
mod group;
|
||||
pub mod settings;
|
||||
|
|
|
@ -29,8 +29,10 @@ use ArgMatches;
|
|||
/// [arguments]: ./struct.Arg.html
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubCommand<'a> {
|
||||
#[doc(hidden)] pub name: String,
|
||||
#[doc(hidden)] pub matches: ArgMatches<'a>,
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub matches: ArgMatches<'a>,
|
||||
}
|
||||
|
||||
impl<'a> SubCommand<'a> {
|
||||
|
|
|
@ -2,19 +2,16 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use app::parser::Parser;
|
||||
use args::{ArgSettings, OptBuilder};
|
||||
use app::App;
|
||||
use args::{Arg, ArgSettings};
|
||||
use completions;
|
||||
|
||||
pub struct BashGen<'a, 'b>
|
||||
pub struct BashGen<'a, 'b>(&'b App<'a, 'b>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
p: &'b Parser<'a, 'b>,
|
||||
}
|
||||
'a: 'b;
|
||||
|
||||
impl<'a, 'b> BashGen<'a, 'b> {
|
||||
pub fn new(p: &'b Parser<'a, 'b>) -> Self { BashGen { p: p } }
|
||||
pub fn new(app: &'b App<'a, 'b>) -> Self { BashGen(app) }
|
||||
|
||||
pub fn generate_to<W: Write>(&self, buf: &mut W) {
|
||||
w!(
|
||||
|
@ -62,10 +59,9 @@ impl<'a, 'b> BashGen<'a, 'b> {
|
|||
|
||||
complete -F _{name} -o bashdefault -o default {name}
|
||||
",
|
||||
name = self.p.meta.bin_name.as_ref().unwrap(),
|
||||
name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()),
|
||||
name_opts_details =
|
||||
self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()),
|
||||
name = self.0.bin_name.as_ref().unwrap(),
|
||||
name_opts = self.all_options_for_path(self.0.bin_name.as_ref().unwrap()),
|
||||
name_opts_details = self.option_details_for_path(self.0.bin_name.as_ref().unwrap()),
|
||||
subcmds = self.all_subcommands(),
|
||||
subcmd_details = self.subcommand_details()
|
||||
).as_bytes()
|
||||
|
@ -75,7 +71,7 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
fn all_subcommands(&self) -> String {
|
||||
debugln!("BashGen::all_subcommands;");
|
||||
let mut subcmds = String::new();
|
||||
let scs = completions::all_subcommand_names(self.p);
|
||||
let scs = completions::all_subcommand_names(self.0);
|
||||
|
||||
for sc in &scs {
|
||||
subcmds = format!(
|
||||
|
@ -95,7 +91,7 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
fn subcommand_details(&self) -> String {
|
||||
debugln!("BashGen::subcommand_details;");
|
||||
let mut subcmd_dets = String::new();
|
||||
let mut scs = completions::get_all_subcommand_paths(self.p, true);
|
||||
let mut scs = completions::get_all_subcommand_paths(self.0, true);
|
||||
scs.sort();
|
||||
scs.dedup();
|
||||
|
||||
|
@ -130,14 +126,14 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
|
||||
fn option_details_for_path(&self, path: &str) -> String {
|
||||
debugln!("BashGen::option_details_for_path: path={}", path);
|
||||
let mut p = self.p;
|
||||
let mut p = self.0;
|
||||
for sc in path.split("__").skip(1) {
|
||||
debugln!("BashGen::option_details_for_path:iter: sc={}", sc);
|
||||
p = &find_subcmd!(p, sc).unwrap().p;
|
||||
p = &find_subcmd!(p, sc).unwrap();
|
||||
}
|
||||
let mut opts = String::new();
|
||||
for o in p.opts() {
|
||||
if let Some(l) = o.s.long {
|
||||
for o in opts!(p) {
|
||||
if let Some(l) = o.long {
|
||||
opts = format!(
|
||||
"{}
|
||||
--{})
|
||||
|
@ -149,7 +145,7 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
self.vals_for(o)
|
||||
);
|
||||
}
|
||||
if let Some(s) = o.s.short {
|
||||
if let Some(s) = o.short {
|
||||
opts = format!(
|
||||
"{}
|
||||
-{})
|
||||
|
@ -165,15 +161,14 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
opts
|
||||
}
|
||||
|
||||
fn vals_for(&self, o: &OptBuilder) -> String {
|
||||
debugln!("BashGen::vals_for: o={}", o.b.name);
|
||||
use args::AnyArg;
|
||||
fn vals_for(&self, o: &Arg) -> String {
|
||||
debugln!("BashGen::vals_for: o={}", o.name);
|
||||
let mut ret = String::new();
|
||||
let mut needs_quotes = true;
|
||||
if let Some(vals) = o.possible_vals() {
|
||||
if let Some(ref vals) = o.possible_vals {
|
||||
needs_quotes = false;
|
||||
ret = format!("$(compgen -W \"{}\" -- ${{cur}})", vals.join(" "));
|
||||
} else if let Some(vec) = o.val_names() {
|
||||
} else if let Some(ref vec) = o.val_names {
|
||||
let mut it = vec.iter().peekable();
|
||||
while let Some((_, val)) = it.next() {
|
||||
ret = format!(
|
||||
|
@ -187,13 +182,13 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
if o.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
ret = format!("{}...", ret);
|
||||
}
|
||||
} else if let Some(num) = o.num_vals() {
|
||||
} else if let Some(num) = o.num_vals {
|
||||
let mut it = (0..num).peekable();
|
||||
while let Some(_) = it.next() {
|
||||
ret = format!(
|
||||
"{}<{}>{}",
|
||||
ret,
|
||||
o.name(),
|
||||
o.name,
|
||||
if it.peek().is_some() { " " } else { "" }
|
||||
);
|
||||
}
|
||||
|
@ -201,7 +196,7 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
ret = format!("{}...", ret);
|
||||
}
|
||||
} else {
|
||||
ret = format!("<{}>", o.name());
|
||||
ret = format!("<{}>", o.name);
|
||||
if o.is_set(ArgSettings::Multiple) {
|
||||
ret = format!("{}...", ret);
|
||||
}
|
||||
|
@ -213,43 +208,20 @@ complete -F _{name} -o bashdefault -o default {name}
|
|||
}
|
||||
fn all_options_for_path(&self, path: &str) -> String {
|
||||
debugln!("BashGen::all_options_for_path: path={}", path);
|
||||
let mut p = self.p;
|
||||
let mut p = self.0;
|
||||
for sc in path.split("__").skip(1) {
|
||||
debugln!("BashGen::all_options_for_path:iter: sc={}", sc);
|
||||
p = &find_subcmd!(p, sc).unwrap().p;
|
||||
p = &find_subcmd!(p, sc).unwrap();
|
||||
}
|
||||
let mut opts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s));
|
||||
opts = format!(
|
||||
"{} {}",
|
||||
opts,
|
||||
longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l))
|
||||
let opts = format!(
|
||||
"{shorts} {longs} {pos} {subcmds}",
|
||||
shorts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s)),
|
||||
// Handles aliases too
|
||||
longs = longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l)),
|
||||
pos = positionals!(p).fold(String::new(), |acc, p| format!("{} {}", acc, p)),
|
||||
// Handles aliases too
|
||||
subcmds = sc_names!(p).fold(String::new(), |acc, s| format!("{} {}", acc, s))
|
||||
);
|
||||
opts = format!(
|
||||
"{} {}",
|
||||
opts,
|
||||
p.positionals
|
||||
.values()
|
||||
.fold(String::new(), |acc, p| format!("{} {}", acc, p))
|
||||
);
|
||||
opts = format!(
|
||||
"{} {}",
|
||||
opts,
|
||||
p.subcommands
|
||||
.iter()
|
||||
.fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))
|
||||
);
|
||||
for sc in &p.subcommands {
|
||||
if let Some(ref aliases) = sc.p.meta.aliases {
|
||||
opts = format!(
|
||||
"{} {}",
|
||||
opts,
|
||||
aliases
|
||||
.iter()
|
||||
.map(|&(n, _)| n)
|
||||
.fold(String::new(), |acc, a| format!("{} {}", acc, a))
|
||||
);
|
||||
}
|
||||
}
|
||||
opts
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,17 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use app::parser::Parser;
|
||||
use app::App;
|
||||
|
||||
pub struct FishGen<'a, 'b>
|
||||
pub struct FishGen<'a, 'b>(&'b App<'a, 'b>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
p: &'b Parser<'a, 'b>,
|
||||
}
|
||||
'a: 'b;
|
||||
|
||||
impl<'a, 'b> FishGen<'a, 'b> {
|
||||
pub fn new(p: &'b Parser<'a, 'b>) -> Self { FishGen { p: p } }
|
||||
pub fn new(app: &'b App<'a, 'b>) -> Self { FishGen(app) }
|
||||
|
||||
pub fn generate_to<W: Write>(&self, buf: &mut W) {
|
||||
let command = self.p.meta.bin_name.as_ref().unwrap();
|
||||
let command = self.0.bin_name.as_ref().unwrap();
|
||||
|
||||
// function to detect subcommand
|
||||
let detect_subcommand_function = r#"function __fish_using_command
|
||||
|
@ -58,48 +55,47 @@ fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, parent_cmds: &str, buf
|
|||
|
||||
let basic_template = format!(
|
||||
"complete -c {} -n \"__fish_using_command {}\"",
|
||||
root_command,
|
||||
parent_cmds
|
||||
root_command, parent_cmds
|
||||
);
|
||||
|
||||
for option in comp_gen.p.opts() {
|
||||
for option in opts!(comp_gen.0) {
|
||||
let mut template = basic_template.clone();
|
||||
if let Some(data) = option.s.short {
|
||||
if let Some(data) = option.short {
|
||||
template.push_str(format!(" -s {}", data).as_str());
|
||||
}
|
||||
if let Some(data) = option.s.long {
|
||||
if let Some(data) = option.long {
|
||||
template.push_str(format!(" -l {}", data).as_str());
|
||||
}
|
||||
if let Some(data) = option.b.help {
|
||||
if let Some(data) = option.help {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
|
||||
}
|
||||
if let Some(ref data) = option.v.possible_vals {
|
||||
if let Some(ref data) = option.possible_vals {
|
||||
template.push_str(format!(" -r -f -a \"{}\"", data.join(" ")).as_str());
|
||||
}
|
||||
buffer.push_str(template.as_str());
|
||||
buffer.push_str("\n");
|
||||
}
|
||||
|
||||
for flag in comp_gen.p.flags() {
|
||||
for flag in flags!(comp_gen.0) {
|
||||
let mut template = basic_template.clone();
|
||||
if let Some(data) = flag.s.short {
|
||||
if let Some(data) = flag.short {
|
||||
template.push_str(format!(" -s {}", data).as_str());
|
||||
}
|
||||
if let Some(data) = flag.s.long {
|
||||
if let Some(data) = flag.long {
|
||||
template.push_str(format!(" -l {}", data).as_str());
|
||||
}
|
||||
if let Some(data) = flag.b.help {
|
||||
if let Some(data) = flag.help {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str());
|
||||
}
|
||||
buffer.push_str(template.as_str());
|
||||
buffer.push_str("\n");
|
||||
}
|
||||
|
||||
for subcommand in &comp_gen.p.subcommands {
|
||||
for subcommand in subcommands!(comp_gen.0) {
|
||||
let mut template = basic_template.clone();
|
||||
template.push_str(" -f");
|
||||
template.push_str(format!(" -a \"{}\"", &subcommand.p.meta.name).as_str());
|
||||
if let Some(data) = subcommand.p.meta.about {
|
||||
template.push_str(format!(" -a \"{}\"", &subcommand.name).as_str());
|
||||
if let Some(data) = subcommand.about {
|
||||
template.push_str(format!(" -d '{}'", escape_string(data)).as_str())
|
||||
}
|
||||
buffer.push_str(template.as_str());
|
||||
|
@ -107,14 +103,14 @@ fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, parent_cmds: &str, buf
|
|||
}
|
||||
|
||||
// generate options of subcommands
|
||||
for subcommand in &comp_gen.p.subcommands {
|
||||
let sub_comp_gen = FishGen::new(&subcommand.p);
|
||||
for subcommand in subcommands!(comp_gen.0) {
|
||||
let sub_comp_gen = FishGen::new(&subcommand);
|
||||
// make new "parent_cmds" for different subcommands
|
||||
let mut sub_parent_cmds = parent_cmds.to_string();
|
||||
if !sub_parent_cmds.is_empty() {
|
||||
sub_parent_cmds.push_str(" ");
|
||||
}
|
||||
sub_parent_cmds.push_str(&subcommand.p.meta.name);
|
||||
sub_parent_cmds.push_str(&subcommand.name);
|
||||
gen_fish_inner(root_command, &sub_comp_gen, &sub_parent_cmds, buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@ macro_rules! w {
|
|||
}
|
||||
|
||||
macro_rules! get_zsh_arg_conflicts {
|
||||
($p:ident, $arg:ident, $msg:ident) => {
|
||||
if let Some(conf_vec) = $arg.blacklist() {
|
||||
($app:expr, $arg:ident, $msg:ident) => {
|
||||
if let Some(ref conf_vec) = $arg.blacklist {
|
||||
let mut v = vec![];
|
||||
for arg_name in conf_vec {
|
||||
let arg = $p.find_any_arg(arg_name).expect($msg);
|
||||
if let Some(s) = arg.short() {
|
||||
let arg = find!($app, arg_name).expect($msg);
|
||||
if let Some(s) = arg.short {
|
||||
v.push(format!("-{}", s));
|
||||
}
|
||||
if let Some(l) = arg.long() {
|
||||
if let Some(l) = arg.long {
|
||||
v.push(format!("--{}", l));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,29 +10,26 @@ mod shell;
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use app::parser::Parser;
|
||||
use app::App;
|
||||
use self::bash::BashGen;
|
||||
use self::fish::FishGen;
|
||||
use self::zsh::ZshGen;
|
||||
use self::powershell::PowerShellGen;
|
||||
pub use self::shell::Shell;
|
||||
|
||||
pub struct ComplGen<'a, 'b>
|
||||
pub struct ComplGen<'a, 'b>(&'b App<'a, 'b>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
p: &'b Parser<'a, 'b>,
|
||||
}
|
||||
'a: 'b;
|
||||
|
||||
impl<'a, 'b> ComplGen<'a, 'b> {
|
||||
pub fn new(p: &'b Parser<'a, 'b>) -> Self { ComplGen { p: p } }
|
||||
pub fn new(app: &'b App<'a, 'b>) -> Self { ComplGen(app) }
|
||||
|
||||
pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) {
|
||||
match for_shell {
|
||||
Shell::Bash => BashGen::new(self.p).generate_to(buf),
|
||||
Shell::Fish => FishGen::new(self.p).generate_to(buf),
|
||||
Shell::Zsh => ZshGen::new(self.p).generate_to(buf),
|
||||
Shell::PowerShell => PowerShellGen::new(self.p).generate_to(buf),
|
||||
Shell::Bash => BashGen::new(self.0).generate_to(buf),
|
||||
Shell::Fish => FishGen::new(self.0).generate_to(buf),
|
||||
Shell::Zsh => ZshGen::new(self.0).generate_to(buf),
|
||||
Shell::PowerShell => PowerShellGen::new(self.0).generate_to(buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +40,13 @@ impl<'a, 'b> ComplGen<'a, 'b> {
|
|||
//
|
||||
// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
// aliasing.
|
||||
pub fn all_subcommand_names(p: &Parser) -> Vec<String> {
|
||||
pub fn all_subcommand_names(p: &App) -> Vec<String> {
|
||||
debugln!("all_subcommand_names;");
|
||||
let mut subcmds: Vec<_> = subcommands_of(p)
|
||||
.iter()
|
||||
.map(|&(ref n, _)| n.clone())
|
||||
.collect();
|
||||
for sc_v in p.subcommands.iter().map(|s| all_subcommand_names(&s.p)) {
|
||||
for sc_v in subcommands!(p).map(|s| all_subcommand_names(&s)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
subcmds.sort();
|
||||
|
@ -63,10 +60,10 @@ pub fn all_subcommand_names(p: &Parser) -> Vec<String> {
|
|||
//
|
||||
// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
// aliasing.
|
||||
pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
|
||||
pub fn all_subcommands(p: &App) -> Vec<(String, String)> {
|
||||
debugln!("all_subcommands;");
|
||||
let mut subcmds: Vec<_> = subcommands_of(p);
|
||||
for sc_v in p.subcommands.iter().map(|s| all_subcommands(&s.p)) {
|
||||
for sc_v in subcommands!(p).map(|s| all_subcommands(&s)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
subcmds
|
||||
|
@ -78,11 +75,11 @@ pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
|
|||
//
|
||||
// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
|
||||
// aliasing.
|
||||
pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
|
||||
pub fn subcommands_of(p: &App) -> Vec<(String, String)> {
|
||||
debugln!(
|
||||
"subcommands_of: name={}, bin_name={}",
|
||||
p.meta.name,
|
||||
p.meta.bin_name.as_ref().unwrap()
|
||||
p.name,
|
||||
p.bin_name.as_ref().unwrap()
|
||||
);
|
||||
let mut subcmds = vec![];
|
||||
|
||||
|
@ -93,11 +90,10 @@ pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
|
|||
if !p.has_subcommands() {
|
||||
let mut ret = vec![];
|
||||
debugln!("subcommands_of: Looking for aliases...");
|
||||
if let Some(ref aliases) = p.meta.aliases {
|
||||
if let Some(ref aliases) = p.aliases {
|
||||
for &(n, _) in aliases {
|
||||
debugln!("subcommands_of:iter:iter: Found alias...{}", n);
|
||||
let mut als_bin_name: Vec<_> =
|
||||
p.meta.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
let mut als_bin_name: Vec<_> = p.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
als_bin_name.push(n);
|
||||
let old = als_bin_name.len() - 2;
|
||||
als_bin_name.swap_remove(old);
|
||||
|
@ -106,42 +102,38 @@ pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
for sc in &p.subcommands {
|
||||
for sc in subcommands!(p) {
|
||||
debugln!(
|
||||
"subcommands_of:iter: name={}, bin_name={}",
|
||||
sc.p.meta.name,
|
||||
sc.p.meta.bin_name.as_ref().unwrap()
|
||||
sc.name,
|
||||
sc.bin_name.as_ref().unwrap()
|
||||
);
|
||||
|
||||
debugln!("subcommands_of:iter: Looking for aliases...");
|
||||
if let Some(ref aliases) = sc.p.meta.aliases {
|
||||
if let Some(ref aliases) = sc.aliases {
|
||||
for &(n, _) in aliases {
|
||||
debugln!("subcommands_of:iter:iter: Found alias...{}", n);
|
||||
let mut als_bin_name: Vec<_> =
|
||||
p.meta.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
let mut als_bin_name: Vec<_> = p.bin_name.as_ref().unwrap().split(' ').collect();
|
||||
als_bin_name.push(n);
|
||||
let old = als_bin_name.len() - 2;
|
||||
als_bin_name.swap_remove(old);
|
||||
subcmds.push((n.to_owned(), als_bin_name.join(" ")));
|
||||
}
|
||||
}
|
||||
subcmds.push((
|
||||
sc.p.meta.name.clone(),
|
||||
sc.p.meta.bin_name.as_ref().unwrap().clone(),
|
||||
));
|
||||
subcmds.push((sc.name.clone(), sc.bin_name.as_ref().unwrap().clone()));
|
||||
}
|
||||
subcmds
|
||||
}
|
||||
|
||||
pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String> {
|
||||
pub fn get_all_subcommand_paths(p: &App, first: bool) -> Vec<String> {
|
||||
debugln!("get_all_subcommand_paths;");
|
||||
let mut subcmds = vec![];
|
||||
if !p.has_subcommands() {
|
||||
if !first {
|
||||
let name = &*p.meta.name;
|
||||
let path = p.meta.bin_name.as_ref().unwrap().clone().replace(" ", "__");
|
||||
let name = &*p.name;
|
||||
let path = p.bin_name.as_ref().unwrap().clone().replace(" ", "__");
|
||||
let mut ret = vec![path.clone()];
|
||||
if let Some(ref aliases) = p.meta.aliases {
|
||||
if let Some(ref aliases) = p.aliases {
|
||||
for &(n, _) in aliases {
|
||||
ret.push(path.replace(name, n));
|
||||
}
|
||||
|
@ -150,26 +142,17 @@ pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec<String> {
|
|||
}
|
||||
return vec![];
|
||||
}
|
||||
for sc in &p.subcommands {
|
||||
let name = &*sc.p.meta.name;
|
||||
let path = sc.p
|
||||
.meta
|
||||
.bin_name
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.replace(" ", "__");
|
||||
for sc in subcommands!(p) {
|
||||
let name = &*sc.name;
|
||||
let path = sc.bin_name.as_ref().unwrap().clone().replace(" ", "__");
|
||||
subcmds.push(path.clone());
|
||||
if let Some(ref aliases) = sc.p.meta.aliases {
|
||||
if let Some(ref aliases) = sc.aliases {
|
||||
for &(n, _) in aliases {
|
||||
subcmds.push(path.replace(name, n));
|
||||
}
|
||||
}
|
||||
}
|
||||
for sc_v in p.subcommands
|
||||
.iter()
|
||||
.map(|s| get_all_subcommand_paths(&s.p, false))
|
||||
{
|
||||
for sc_v in subcommands!(p).map(|s| get_all_subcommand_paths(&s, false)) {
|
||||
subcmds.extend(sc_v);
|
||||
}
|
||||
subcmds
|
||||
|
|
|
@ -2,25 +2,22 @@
|
|||
use std::io::Write;
|
||||
|
||||
// Internal
|
||||
use app::parser::Parser;
|
||||
use app::App;
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
pub struct PowerShellGen<'a, 'b>
|
||||
pub struct PowerShellGen<'a, 'b>(&'b App<'a, 'b>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
p: &'b Parser<'a, 'b>,
|
||||
}
|
||||
'a: 'b;
|
||||
|
||||
impl<'a, 'b> PowerShellGen<'a, 'b> {
|
||||
pub fn new(p: &'b Parser<'a, 'b>) -> Self { PowerShellGen { p: p } }
|
||||
pub fn new(app: &'b App<'a, 'b>) -> Self { PowerShellGen(app) }
|
||||
|
||||
pub fn generate_to<W: Write>(&self, buf: &mut W) {
|
||||
let bin_name = self.p.meta.bin_name.as_ref().unwrap();
|
||||
let bin_name = self.0.bin_name.as_ref().unwrap();
|
||||
|
||||
let mut names = vec![];
|
||||
let (subcommands_detection_cases, subcommands_cases) =
|
||||
generate_inner(self.p, "", &mut names);
|
||||
generate_inner(self.0, "", &mut names);
|
||||
|
||||
let mut bin_names = vec![bin_name.to_string(), format!("./{0}", bin_name)];
|
||||
if cfg!(windows) {
|
||||
|
@ -76,7 +73,7 @@ impl<'a, 'b> PowerShellGen<'a, 'b> {
|
|||
}
|
||||
|
||||
fn generate_inner<'a, 'b, 'p>(
|
||||
p: &'p Parser<'a, 'b>,
|
||||
p: &'p App<'a, 'b>,
|
||||
previous_command_name: &str,
|
||||
names: &mut Vec<&'p str>,
|
||||
) -> (String, String) {
|
||||
|
@ -85,14 +82,14 @@ fn generate_inner<'a, 'b, 'p>(
|
|||
format!(
|
||||
"{}_{}",
|
||||
previous_command_name,
|
||||
&p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG)
|
||||
&p.bin_name.as_ref().expect(INTERNAL_ERROR_MSG)
|
||||
)
|
||||
} else {
|
||||
format!("{}_{}", previous_command_name, &p.meta.name)
|
||||
format!("{}_{}", previous_command_name, &p.name)
|
||||
};
|
||||
|
||||
let mut subcommands_detection_cases = if !names.contains(&&*p.meta.name) {
|
||||
names.push(&*p.meta.name);
|
||||
let mut subcommands_detection_cases = if !names.contains(&&*p.name) {
|
||||
names.push(&*p.name);
|
||||
format!(
|
||||
r"
|
||||
'{0}' {{
|
||||
|
@ -100,7 +97,7 @@ fn generate_inner<'a, 'b, 'p>(
|
|||
break
|
||||
}}
|
||||
",
|
||||
&p.meta.name
|
||||
&p.name
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
|
@ -108,7 +105,7 @@ fn generate_inner<'a, 'b, 'p>(
|
|||
|
||||
let mut completions = String::new();
|
||||
for subcommand in &p.subcommands {
|
||||
completions.push_str(&format!("'{}', ", &subcommand.p.meta.name));
|
||||
completions.push_str(&format!("'{}', ", &subcommand.name));
|
||||
}
|
||||
for short in shorts!(p) {
|
||||
completions.push_str(&format!("'-{}', ", short));
|
||||
|
@ -127,9 +124,9 @@ fn generate_inner<'a, 'b, 'p>(
|
|||
completions.trim_right_matches(", ")
|
||||
);
|
||||
|
||||
for subcommand in &p.subcommands {
|
||||
for subcommand in subcommands!(p) {
|
||||
let (subcommand_subcommands_detection_cases, subcommand_subcommands_cases) =
|
||||
generate_inner(&subcommand.p, &command_name, names);
|
||||
generate_inner(&subcommand, &command_name, names);
|
||||
subcommands_detection_cases.push_str(&subcommand_subcommands_detection_cases);
|
||||
subcommands_cases.push_str(&subcommand_subcommands_cases);
|
||||
}
|
||||
|
|
|
@ -5,22 +5,18 @@ use std::ascii::AsciiExt;
|
|||
|
||||
// Internal
|
||||
use app::App;
|
||||
use app::parser::Parser;
|
||||
use args::{AnyArg, ArgSettings};
|
||||
use args::ArgSettings;
|
||||
use completions;
|
||||
use INTERNAL_ERROR_MSG;
|
||||
|
||||
pub struct ZshGen<'a, 'b>
|
||||
pub struct ZshGen<'a, 'b>(&'b App<'a, 'b>)
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
p: &'b Parser<'a, 'b>,
|
||||
}
|
||||
'a: 'b;
|
||||
|
||||
impl<'a, 'b> ZshGen<'a, 'b> {
|
||||
pub fn new(p: &'b Parser<'a, 'b>) -> Self {
|
||||
pub fn new(app: &'b App<'a, 'b>) -> Self {
|
||||
debugln!("ZshGen::new;");
|
||||
ZshGen { p: p }
|
||||
ZshGen(app)
|
||||
}
|
||||
|
||||
pub fn generate_to<W: Write>(&self, buf: &mut W) {
|
||||
|
@ -52,10 +48,10 @@ _{name}() {{
|
|||
{subcommand_details}
|
||||
|
||||
_{name} \"$@\"",
|
||||
name = self.p.meta.bin_name.as_ref().unwrap(),
|
||||
initial_args = get_args_of(self.p),
|
||||
subcommands = get_subcommands_of(self.p),
|
||||
subcommand_details = subcommand_details(self.p)
|
||||
name = self.0.bin_name.as_ref().unwrap(),
|
||||
initial_args = get_args_of(self.0),
|
||||
subcommands = get_subcommands_of(self.0),
|
||||
subcommand_details = subcommand_details(self.0)
|
||||
).as_bytes()
|
||||
);
|
||||
}
|
||||
|
@ -88,7 +84,7 @@ _{name} \"$@\"",
|
|||
// )
|
||||
// _describe -t commands 'rustup commands' commands "$@"
|
||||
//
|
||||
fn subcommand_details(p: &Parser) -> String {
|
||||
fn subcommand_details(p: &App) -> String {
|
||||
debugln!("ZshGen::subcommand_details;");
|
||||
// First we do ourself
|
||||
let mut ret = vec![
|
||||
|
@ -101,8 +97,8 @@ _{bin_name_underscore}_commands() {{
|
|||
)
|
||||
_describe -t commands '{bin_name} commands' commands \"$@\"
|
||||
}}",
|
||||
bin_name_underscore = p.meta.bin_name.as_ref().unwrap().replace(" ", "__"),
|
||||
bin_name = p.meta.bin_name.as_ref().unwrap(),
|
||||
bin_name_underscore = p.bin_name.as_ref().unwrap().replace(" ", "__"),
|
||||
bin_name = p.bin_name.as_ref().unwrap(),
|
||||
subcommands_and_args = subcommands_of(p)
|
||||
),
|
||||
];
|
||||
|
@ -142,7 +138,7 @@ _{bin_name_underscore}_commands() {{
|
|||
// A snippet from rustup:
|
||||
// 'show:Show the active and installed toolchains'
|
||||
// 'update:Update Rust toolchains'
|
||||
fn subcommands_of(p: &Parser) -> String {
|
||||
fn subcommands_of(p: &App) -> String {
|
||||
debugln!("ZshGen::subcommands_of;");
|
||||
let mut ret = vec![];
|
||||
fn add_sc(sc: &App, n: &str, ret: &mut Vec<String>) {
|
||||
|
@ -150,9 +146,7 @@ fn subcommands_of(p: &Parser) -> String {
|
|||
let s = format!(
|
||||
"\"{name}:{help}\" \\",
|
||||
name = n,
|
||||
help = sc.p
|
||||
.meta
|
||||
.about
|
||||
help = sc.about
|
||||
.unwrap_or("")
|
||||
.replace("[", "\\[")
|
||||
.replace("]", "\\]")
|
||||
|
@ -163,13 +157,10 @@ fn subcommands_of(p: &Parser) -> String {
|
|||
}
|
||||
|
||||
// The subcommands
|
||||
for sc in p.subcommands() {
|
||||
debugln!(
|
||||
"ZshGen::subcommands_of:iter: subcommand={}",
|
||||
sc.p.meta.name
|
||||
);
|
||||
add_sc(sc, &sc.p.meta.name, &mut ret);
|
||||
if let Some(ref v) = sc.p.meta.aliases {
|
||||
for sc in subcommands!(p) {
|
||||
debugln!("ZshGen::subcommands_of:iter: subcommand={}", sc.name);
|
||||
add_sc(sc, &sc.name, &mut ret);
|
||||
if let Some(ref v) = sc.aliases {
|
||||
for alias in v.iter().filter(|&&(_, vis)| vis).map(|&(n, _)| n) {
|
||||
add_sc(sc, alias, &mut ret);
|
||||
}
|
||||
|
@ -208,7 +199,7 @@ fn subcommands_of(p: &Parser) -> String {
|
|||
// [name_hyphen] = The full space deliniated bin_name, but replace spaces with hyphens
|
||||
// [repeat] = From the same recursive calls, but for all subcommands
|
||||
// [subcommand_args] = The same as zsh::get_args_of
|
||||
fn get_subcommands_of(p: &Parser) -> String {
|
||||
fn get_subcommands_of(p: &App) -> String {
|
||||
debugln!("get_subcommands_of;");
|
||||
|
||||
debugln!(
|
||||
|
@ -247,19 +238,20 @@ fn get_subcommands_of(p: &Parser) -> String {
|
|||
esac
|
||||
;;
|
||||
esac",
|
||||
name = p.meta.name,
|
||||
name_hyphen = p.meta.bin_name.as_ref().unwrap().replace(" ", "-"),
|
||||
name = p.name,
|
||||
name_hyphen = p.bin_name.as_ref().unwrap().replace(" ", "-"),
|
||||
subcommands = subcmds.join("\n"),
|
||||
pos = p.positionals().len() + 1
|
||||
pos = positionals!(p).count() + 1
|
||||
)
|
||||
}
|
||||
|
||||
fn parser_of<'a, 'b>(p: &'b Parser<'a, 'b>, sc: &str) -> &'b Parser<'a, 'b> {
|
||||
fn parser_of<'a, 'b>(p: &'b App<'a, 'b>, mut sc: &str) -> &'b App<'a, 'b> {
|
||||
debugln!("parser_of: sc={}", sc);
|
||||
if sc == p.meta.bin_name.as_ref().unwrap_or(&String::new()) {
|
||||
if sc == p.bin_name.as_ref().unwrap_or(&String::new()) {
|
||||
return p;
|
||||
}
|
||||
&p.find_subcommand(sc).expect(INTERNAL_ERROR_MSG).p
|
||||
sc = sc.split(" ").last().unwrap();
|
||||
find_subcmd!(p, sc).expect(INTERNAL_ERROR_MSG)
|
||||
}
|
||||
|
||||
// Writes out the args section, which ends up being the flags, opts and postionals, and a jump to
|
||||
|
@ -282,7 +274,7 @@ fn parser_of<'a, 'b>(p: &'b Parser<'a, 'b>, sc: &str) -> &'b Parser<'a, 'b> {
|
|||
// -C: modify the $context internal variable
|
||||
// -s: Allow stacking of short args (i.e. -a -b -c => -abc)
|
||||
// -S: Do not complete anything after '--' and treat those as argument values
|
||||
fn get_args_of(p: &Parser) -> String {
|
||||
fn get_args_of(p: &App) -> String {
|
||||
debugln!("get_args_of;");
|
||||
let mut ret = vec![String::from("_arguments \"${_arguments_options[@]}\" \\")];
|
||||
let opts = write_opts_of(p);
|
||||
|
@ -291,13 +283,13 @@ fn get_args_of(p: &Parser) -> String {
|
|||
let sc_or_a = if p.has_subcommands() {
|
||||
format!(
|
||||
"\":: :_{name}_commands\" \\",
|
||||
name = p.meta.bin_name.as_ref().unwrap().replace(" ", "__")
|
||||
name = p.bin_name.as_ref().unwrap().replace(" ", "__")
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let sc = if p.has_subcommands() {
|
||||
format!("\"*::: :->{name}\" \\", name = p.meta.name)
|
||||
format!("\"*::: :->{name}\" \\", name = p.name)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
@ -341,12 +333,12 @@ fn escape_value(string: &str) -> String {
|
|||
.replace(" ", "\\ ")
|
||||
}
|
||||
|
||||
fn write_opts_of(p: &Parser) -> String {
|
||||
fn write_opts_of(p: &App) -> String {
|
||||
debugln!("write_opts_of;");
|
||||
let mut ret = vec![];
|
||||
for o in p.opts() {
|
||||
debugln!("write_opts_of:iter: o={}", o.name());
|
||||
let help = o.help().map_or(String::new(), escape_help);
|
||||
for o in opts!(p) {
|
||||
debugln!("write_opts_of:iter: o={}", o.name);
|
||||
let help = o.help.map_or(String::new(), escape_help);
|
||||
let mut conflicts = get_zsh_arg_conflicts!(p, o, INTERNAL_ERROR_MSG);
|
||||
conflicts = if conflicts.is_empty() {
|
||||
String::new()
|
||||
|
@ -359,13 +351,19 @@ fn write_opts_of(p: &Parser) -> String {
|
|||
} else {
|
||||
""
|
||||
};
|
||||
let pv = if let Some(pv_vec) = o.possible_vals() {
|
||||
format!(": :({})", pv_vec.iter().map(
|
||||
|v| escape_value(*v)).collect::<Vec<String>>().join(" "))
|
||||
let pv = if let Some(ref pv_vec) = o.possible_vals {
|
||||
format!(
|
||||
": :({})",
|
||||
pv_vec
|
||||
.iter()
|
||||
.map(|v| escape_value(*v))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
if let Some(short) = o.short() {
|
||||
if let Some(short) = o.short {
|
||||
let s = format!(
|
||||
"'{conflicts}{multiple}-{arg}+[{help}]{possible_values}' \\",
|
||||
conflicts = conflicts,
|
||||
|
@ -378,7 +376,7 @@ fn write_opts_of(p: &Parser) -> String {
|
|||
debugln!("write_opts_of:iter: Wrote...{}", &*s);
|
||||
ret.push(s);
|
||||
}
|
||||
if let Some(long) = o.long() {
|
||||
if let Some(long) = o.long {
|
||||
let l = format!(
|
||||
"'{conflicts}{multiple}--{arg}=[{help}]{possible_values}' \\",
|
||||
conflicts = conflicts,
|
||||
|
@ -396,12 +394,12 @@ fn write_opts_of(p: &Parser) -> String {
|
|||
ret.join("\n")
|
||||
}
|
||||
|
||||
fn write_flags_of(p: &Parser) -> String {
|
||||
fn write_flags_of(p: &App) -> String {
|
||||
debugln!("write_flags_of;");
|
||||
let mut ret = vec![];
|
||||
for f in p.flags() {
|
||||
debugln!("write_flags_of:iter: f={}", f.name());
|
||||
let help = f.help().map_or(String::new(), escape_help);
|
||||
for f in flags!(p) {
|
||||
debugln!("write_flags_of:iter: f={}", f.name);
|
||||
let help = f.help.map_or(String::new(), escape_help);
|
||||
let mut conflicts = get_zsh_arg_conflicts!(p, f, INTERNAL_ERROR_MSG);
|
||||
conflicts = if conflicts.is_empty() {
|
||||
String::new()
|
||||
|
@ -414,7 +412,7 @@ fn write_flags_of(p: &Parser) -> String {
|
|||
} else {
|
||||
""
|
||||
};
|
||||
if let Some(short) = f.short() {
|
||||
if let Some(short) = f.short {
|
||||
let s = format!(
|
||||
"'{conflicts}{multiple}-{arg}[{help}]' \\",
|
||||
multiple = multiple,
|
||||
|
@ -427,7 +425,7 @@ fn write_flags_of(p: &Parser) -> String {
|
|||
ret.push(s);
|
||||
}
|
||||
|
||||
if let Some(long) = f.long() {
|
||||
if let Some(long) = f.long {
|
||||
let l = format!(
|
||||
"'{conflicts}{multiple}--{arg}[{help}]' \\",
|
||||
conflicts = conflicts,
|
||||
|
@ -444,24 +442,33 @@ fn write_flags_of(p: &Parser) -> String {
|
|||
ret.join("\n")
|
||||
}
|
||||
|
||||
fn write_positionals_of(p: &Parser) -> String {
|
||||
fn write_positionals_of(p: &App) -> String {
|
||||
debugln!("write_positionals_of;");
|
||||
let mut ret = vec![];
|
||||
for arg in p.positionals() {
|
||||
debugln!("write_positionals_of:iter: arg={}", arg.b.name);
|
||||
for arg in positionals!(p) {
|
||||
debugln!("write_positionals_of:iter: arg={}", arg.name);
|
||||
let a = format!(
|
||||
"'{optional}:{name}{help}:{action}' \\",
|
||||
optional = if !arg.b.is_set(ArgSettings::Required) { ":" } else { "" },
|
||||
name = arg.b.name,
|
||||
help = arg.b
|
||||
.help
|
||||
optional = if !arg.is_set(ArgSettings::Required) {
|
||||
":"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
name = arg.name,
|
||||
help = arg.help
|
||||
.map_or("".to_owned(), |v| " -- ".to_owned() + v)
|
||||
.replace("[", "\\[")
|
||||
.replace("]", "\\]"),
|
||||
action = arg.possible_vals().map_or("_files".to_owned(), |values| {
|
||||
format!("({})",
|
||||
values.iter().map(|v| escape_value(*v)).collect::<Vec<String>>().join(" "))
|
||||
})
|
||||
action = arg.possible_vals
|
||||
.as_ref()
|
||||
.map_or("_files".to_owned(), |values| format!(
|
||||
"({})",
|
||||
values
|
||||
.iter()
|
||||
.map(|v| escape_value(*v))
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
))
|
||||
);
|
||||
|
||||
debugln!("write_positionals_of:iter: Wrote...{}", a);
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::process;
|
|||
use std::result::Result as StdResult;
|
||||
|
||||
// Internal
|
||||
use args::AnyArg;
|
||||
use args::Arg;
|
||||
use fmt::{ColorWhen, Colorizer, ColorizerOption};
|
||||
use suggestions;
|
||||
|
||||
|
@ -405,7 +405,7 @@ impl Error {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub fn argument_conflict<'a, 'b, O, U>(
|
||||
arg: &AnyArg,
|
||||
arg: &Arg,
|
||||
other: Option<O>,
|
||||
usage: U,
|
||||
color: ColorWhen,
|
||||
|
@ -414,7 +414,7 @@ impl Error {
|
|||
O: Into<String>,
|
||||
U: Display,
|
||||
{
|
||||
let mut v = vec![arg.name().to_owned()];
|
||||
let mut v = vec![arg.name.to_owned()];
|
||||
let c = Colorizer::new(ColorizerOption {
|
||||
use_stderr: true,
|
||||
when: color,
|
||||
|
@ -443,7 +443,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn empty_value<'a, 'b, U>(arg: &AnyArg, usage: U, color: ColorWhen) -> Self
|
||||
pub fn empty_value<'a, 'b, U>(arg: &Arg, usage: U, color: ColorWhen) -> Self
|
||||
where
|
||||
U: Display,
|
||||
{
|
||||
|
@ -463,7 +463,7 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::EmptyValue,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ impl Error {
|
|||
pub fn invalid_value<'a, 'b, B, G, U>(
|
||||
bad_val: B,
|
||||
good_vals: &[G],
|
||||
arg: &AnyArg,
|
||||
arg: &Arg,
|
||||
usage: U,
|
||||
color: ColorWhen,
|
||||
) -> Self
|
||||
|
@ -509,7 +509,7 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::InvalidValue,
|
||||
info: Some(vec![arg.name().to_owned(), bad_val.as_ref().to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned(), bad_val.as_ref().to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +632,6 @@ impl Error {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn invalid_utf8<U>(usage: U, color: ColorWhen) -> Self
|
||||
where
|
||||
|
@ -657,7 +656,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn too_many_values<'a, 'b, V, U>(val: V, arg: &AnyArg, usage: U, color: ColorWhen) -> Self
|
||||
pub fn too_many_values<'a, 'b, V, U>(val: V, arg: &Arg, usage: U, color: ColorWhen) -> Self
|
||||
where
|
||||
V: AsRef<str> + Display + ToOwned,
|
||||
U: Display,
|
||||
|
@ -680,13 +679,13 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::TooManyValues,
|
||||
info: Some(vec![arg.name().to_owned(), v.to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned(), v.to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn too_few_values<'a, 'b, U>(
|
||||
arg: &AnyArg,
|
||||
arg: &Arg,
|
||||
min_vals: u64,
|
||||
curr_vals: usize,
|
||||
usage: U,
|
||||
|
@ -714,13 +713,12 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::TooFewValues,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn value_validation<'a, 'b>(arg: Option<&AnyArg>, err: String, color: ColorWhen) -> Self
|
||||
{
|
||||
pub fn value_validation<'a, 'b>(arg: Option<&Arg>, err: String, color: ColorWhen) -> Self {
|
||||
let c = Colorizer::new(ColorizerOption {
|
||||
use_stderr: true,
|
||||
when: color,
|
||||
|
@ -743,13 +741,13 @@ impl Error {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub fn value_validation_auto(err: String) -> Self {
|
||||
let n: Option<&AnyArg> = None;
|
||||
let n: Option<&Arg> = None;
|
||||
Error::value_validation(n, err, ColorWhen::Auto)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn wrong_number_of_values<'a, 'b, S, U>(
|
||||
arg: &AnyArg,
|
||||
arg: &Arg,
|
||||
num_vals: u64,
|
||||
curr_vals: usize,
|
||||
suffix: S,
|
||||
|
@ -779,12 +777,12 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::WrongNumberOfValues,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn unexpected_multiple_usage<'a, 'b, U>(arg: &AnyArg, usage: U, color: ColorWhen) -> Self
|
||||
pub fn unexpected_multiple_usage<'a, 'b, U>(arg: &Arg, usage: U, color: ColorWhen) -> Self
|
||||
where
|
||||
U: Display,
|
||||
{
|
||||
|
@ -804,7 +802,7 @@ impl Error {
|
|||
c.good("--help")
|
||||
),
|
||||
kind: ErrorKind::UnexpectedMultipleUsage,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
info: Some(vec![arg.name.to_owned()]),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,6 @@ impl<T: fmt::Display> Format<T> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
||||
impl<T: AsRef<str>> fmt::Display for Format<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", &self.format()) }
|
||||
|
|
|
@ -534,6 +534,7 @@ extern crate ansi_term;
|
|||
extern crate atty;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate ordermap;
|
||||
#[cfg(feature = "suggestions")]
|
||||
extern crate strsim;
|
||||
#[cfg(feature = "wrap_help")]
|
||||
|
@ -548,7 +549,7 @@ extern crate yaml_rust;
|
|||
#[cfg(feature = "yaml")]
|
||||
pub use yaml_rust::YamlLoader;
|
||||
pub use args::{Arg, ArgGroup, ArgMatches, ArgSettings, OsValues, SubCommand, Values};
|
||||
pub use app::{App, AppSettings};
|
||||
pub use app::{App, AppSettings, Propagation};
|
||||
pub use fmt::Format;
|
||||
pub use errors::{Error, ErrorKind, Result};
|
||||
pub use completions::Shell;
|
||||
|
@ -594,7 +595,6 @@ mod derive {
|
|||
Self::try_from_argmatches(Self::into_app().get_matches_safe()?)
|
||||
}
|
||||
|
||||
|
||||
/// @TODO @release @docs
|
||||
fn try_parse_from<I, T>(argv: I) -> Result<Self, clap::Error>
|
||||
where
|
||||
|
|
364
src/macros.rs
364
src/macros.rs
|
@ -852,38 +852,120 @@ macro_rules! write_nspaces {
|
|||
})
|
||||
}
|
||||
|
||||
// convenience macro for remove an item from a vec
|
||||
//macro_rules! vec_remove_all {
|
||||
// ($vec:expr, $to_rem:expr) => {
|
||||
// debugln!("vec_remove_all! to_rem={:?}", $to_rem);
|
||||
// for i in (0 .. $vec.len()).rev() {
|
||||
// let should_remove = $to_rem.any(|name| name == &$vec[i]);
|
||||
// if should_remove { $vec.swap_remove(i); }
|
||||
// }
|
||||
// };
|
||||
//}
|
||||
macro_rules! args {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.args.$how()
|
||||
};
|
||||
($app:expr) => {
|
||||
args!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! args_mut {
|
||||
($app:expr) => {
|
||||
args!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! flags {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.args.$how()
|
||||
.filter(|a| !a.settings.is_set(::args::settings::ArgSettings::TakesValue))
|
||||
.filter(|a| a.short.is_some() || a.long.is_some())
|
||||
};
|
||||
($app:expr) => {
|
||||
flags!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! flags_mut {
|
||||
($app:expr) => {
|
||||
flags!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! opts {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.args.$how()
|
||||
.filter(|a| a.settings.is_set(::args::settings::ArgSettings::TakesValue))
|
||||
.filter(|a| a.short.is_some() || a.long.is_some())
|
||||
};
|
||||
($app:expr) => {
|
||||
opts!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! opts_mut {
|
||||
($app:expr) => {
|
||||
opts!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! positionals {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.args.$how().filter(|a| !(a.short.is_some() || a.long.is_some()))
|
||||
};
|
||||
($app:expr) => {
|
||||
positionals!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! positionals_mut {
|
||||
($app:expr) => {
|
||||
positionals!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! subcommands_cloned {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.subcommands.$how().cloned()
|
||||
};
|
||||
($app:expr) => {
|
||||
subcommands_cloned!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! subcommands {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.subcommands.$how()
|
||||
};
|
||||
($app:expr) => {
|
||||
subcommands!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! subcommands_mut {
|
||||
($app:expr) => {
|
||||
subcommands!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! groups {
|
||||
($app:expr, $how:ident) => {
|
||||
$app.groups.$how()
|
||||
};
|
||||
($app:expr) => {
|
||||
groups!($app, iter)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! groups_mut {
|
||||
($app:expr) => {
|
||||
groups!($app, iter_mut)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! find_from {
|
||||
($_self:expr, $arg_name:expr, $from:ident, $matcher:expr) => {{
|
||||
($app:expr, $arg_name:expr, $from:ident, $matcher:expr) => {{
|
||||
let mut ret = None;
|
||||
for k in $matcher.arg_names() {
|
||||
if let Some(f) = find_by_name!($_self, k, flags, iter) {
|
||||
if let Some(ref v) = f.$from() {
|
||||
if let Some(a) = find!($app, k) {
|
||||
if let Some(ref v) = a.$from {
|
||||
if v.contains($arg_name) {
|
||||
ret = Some(f.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(o) = find_by_name!($_self, k, opts, iter) {
|
||||
if let Some(ref v) = o.$from() {
|
||||
if v.contains(&$arg_name) {
|
||||
ret = Some(o.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(pos) = find_by_name!($_self, k, positionals, values) {
|
||||
if let Some(ref v) = pos.$from() {
|
||||
if v.contains($arg_name) {
|
||||
ret = Some(pos.b.name.to_owned());
|
||||
ret = Some(a.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -892,188 +974,114 @@ macro_rules! find_from {
|
|||
}};
|
||||
}
|
||||
|
||||
//macro_rules! find_name_from {
|
||||
// ($_self:expr, $arg_name:expr, $from:ident, $matcher:expr) => {{
|
||||
// let mut ret = None;
|
||||
// for k in $matcher.arg_names() {
|
||||
// if let Some(f) = find_by_name!($_self, k, flags, iter) {
|
||||
// if let Some(ref v) = f.$from() {
|
||||
// if v.contains($arg_name) {
|
||||
// ret = Some(f.b.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if let Some(o) = find_by_name!($_self, k, opts, iter) {
|
||||
// if let Some(ref v) = o.$from() {
|
||||
// if v.contains(&$arg_name) {
|
||||
// ret = Some(o.b.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if let Some(pos) = find_by_name!($_self, k, positionals, values) {
|
||||
// if let Some(ref v) = pos.$from() {
|
||||
// if v.contains($arg_name) {
|
||||
// ret = Some(pos.b.name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ret
|
||||
// }};
|
||||
//}
|
||||
|
||||
|
||||
macro_rules! find_any_by_name {
|
||||
($p:expr, $name:expr) => {
|
||||
{
|
||||
fn as_trait_obj<'a, 'b, T: AnyArg<'a, 'b>>(x: &T) -> &AnyArg<'a, 'b> { x }
|
||||
find_by_name!($p, $name, flags, iter).map(as_trait_obj).or(
|
||||
find_by_name!($p, $name, opts, iter).map(as_trait_obj).or(
|
||||
find_by_name!($p, $name, positionals, values).map(as_trait_obj)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finds an arg by name
|
||||
macro_rules! find_by_name {
|
||||
($p:expr, $name:expr, $what:ident, $how:ident) => {
|
||||
$p.$what.$how().find(|o| o.b.name == $name)
|
||||
macro_rules! find {
|
||||
($app:expr, $name:expr, $what:ident) => {
|
||||
$what!($app).find(|a| &a.name == $name)
|
||||
};
|
||||
($app:expr, $name:expr) => {
|
||||
$app.args.iter().find(|a| &a.name == $name)
|
||||
}
|
||||
}
|
||||
|
||||
// Finds an option including if it's aliasesed
|
||||
macro_rules! find_opt_by_long {
|
||||
(@os $_self:ident, $long:expr) => {{
|
||||
_find_by_long!($_self, $long, opts)
|
||||
macro_rules! find_by_long {
|
||||
($app:expr, $long:expr, $what:ident) => {{
|
||||
$what!($app)
|
||||
.filter(|a| a.long.is_some())
|
||||
.find(|a| match_alias!(a, $long, a.long.unwrap()))
|
||||
}};
|
||||
($_self:ident, $long:expr) => {{
|
||||
_find_by_long!($_self, $long, opts)
|
||||
($app:expr, $long:expr) => {{
|
||||
$app.args.iter()
|
||||
.filter(|a| a.long.is_some())
|
||||
.find(|a| match_alias!(a, $long, a.long.unwrap()))
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! find_flag_by_long {
|
||||
(@os $_self:ident, $long:expr) => {{
|
||||
_find_by_long!($_self, $long, flags)
|
||||
macro_rules! find_by_short {
|
||||
($app:expr, $short:expr, $what:ident) => {{
|
||||
$what!($app)
|
||||
.find(|a| a.short == Some($short))
|
||||
}};
|
||||
($_self:ident, $long:expr) => {{
|
||||
_find_by_long!($_self, $long, flags)
|
||||
($app:expr, $short:expr) => {{
|
||||
$app.args.iter()
|
||||
.find(|a| a.short == Some($short))
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! find_subcmd_cloned {
|
||||
($_self:expr, $sc:expr) => {{
|
||||
subcommands_cloned!($_self)
|
||||
.find(|a| match_alias!(a, $sc, &*a.name))
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! _find_by_long {
|
||||
($_self:ident, $long:expr, $what:ident) => {{
|
||||
$_self.$what
|
||||
.iter()
|
||||
.filter(|a| a.s.long.is_some())
|
||||
.find(|a| {
|
||||
a.s.long.unwrap() == $long ||
|
||||
(a.s.aliases.is_some() &&
|
||||
a.s
|
||||
.aliases
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|&(alias, _)| alias == $long))
|
||||
})
|
||||
}}
|
||||
}
|
||||
|
||||
// Finds an option
|
||||
macro_rules! find_opt_by_short {
|
||||
($_self:ident, $short:expr) => {{
|
||||
_find_by_short!($_self, $short, opts)
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! find_flag_by_short {
|
||||
($_self:ident, $short:expr) => {{
|
||||
_find_by_short!($_self, $short, flags)
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! _find_by_short {
|
||||
($_self:ident, $short:expr, $what:ident) => {{
|
||||
$_self.$what
|
||||
.iter()
|
||||
.filter(|a| a.s.short.is_some())
|
||||
.find(|a| a.s.short.unwrap() == $short)
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! find_subcmd {
|
||||
($_self:expr, $sc:expr) => {{
|
||||
$_self.subcommands
|
||||
.iter()
|
||||
.find(|s| {
|
||||
&*s.p.meta.name == $sc ||
|
||||
(s.p.meta.aliases.is_some() &&
|
||||
s.p
|
||||
.meta
|
||||
.aliases
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|&(n, _)| n == $sc))
|
||||
})
|
||||
($app:expr, $sc:expr) => {{
|
||||
subcommands!($app)
|
||||
.find(|a| match_alias!(a, $sc, &*a.name))
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! shorts {
|
||||
($_self:ident) => {{
|
||||
_shorts_longs!($_self, short)
|
||||
($app:expr) => {{
|
||||
_shorts_longs!($app, short)
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
macro_rules! longs {
|
||||
($_self:ident) => {{
|
||||
_shorts_longs!($_self, long)
|
||||
($app:expr) => {{
|
||||
$app.args.iter()
|
||||
.filter(|a| a.long.is_some())
|
||||
.map(|a| a.long.unwrap())
|
||||
.chain($app.args.iter()
|
||||
.filter(|a| a.aliases.is_some())
|
||||
.flat_map(|a| a.aliases.as_ref().unwrap().iter().map(|als| als.0)))
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! _shorts_longs {
|
||||
($_self:ident, $what:ident) => {{
|
||||
$_self.flags
|
||||
.iter()
|
||||
.filter(|f| f.s.$what.is_some())
|
||||
.map(|f| f.s.$what.as_ref().unwrap())
|
||||
.chain($_self.opts.iter()
|
||||
.filter(|o| o.s.$what.is_some())
|
||||
.map(|o| o.s.$what.as_ref().unwrap()))
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! arg_names {
|
||||
($_self:ident) => {{
|
||||
_names!(@args $_self)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! sc_names {
|
||||
($_self:ident) => {{
|
||||
_names!(@sc $_self)
|
||||
($app:expr, $what:ident) => {{
|
||||
$app.args.iter().filter_map(|a| a.$what)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! _names {
|
||||
(@args $_self:ident) => {{
|
||||
$_self.flags
|
||||
.iter()
|
||||
.map(|f| &*f.b.name)
|
||||
.chain($_self.opts.iter()
|
||||
.map(|o| &*o.b.name)
|
||||
.chain($_self.positionals.values()
|
||||
.map(|p| &*p.b.name)))
|
||||
(@args $app:expr) => {{
|
||||
$app.args.iter().map(|a| &*a.name)
|
||||
}};
|
||||
(@sc $_self:ident) => {{
|
||||
$_self.subcommands
|
||||
(@sc $app:expr) => {{
|
||||
$app.subcommands
|
||||
.iter()
|
||||
.map(|s| &*s.p.meta.name)
|
||||
.chain($_self.subcommands
|
||||
.map(|s| &*s.name)
|
||||
.chain($app.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.p.meta.aliases.is_some())
|
||||
.flat_map(|s| s.p.meta.aliases.as_ref().unwrap().iter().map(|&(n, _)| n)))
|
||||
.filter(|s| s.aliases.is_some())
|
||||
.flat_map(|s| s.aliases.as_ref().unwrap().iter().map(|&(n, _)| n)))
|
||||
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! arg_names {
|
||||
($app:expr) => {{
|
||||
_names!(@args $app)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! sc_names {
|
||||
($app:expr) => {{
|
||||
_names!(@sc $app)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! match_alias {
|
||||
($a:expr, $to:expr, $what:expr) => {{
|
||||
$what == $to ||
|
||||
($a.aliases.is_some() &&
|
||||
$a.aliases
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|alias| alias.0 == $to))
|
||||
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use app::App;
|
||||
// Third Party
|
||||
#[cfg(feature = "suggestions")]
|
||||
use strsim;
|
||||
|
||||
// Internal
|
||||
use fmt::Format;
|
||||
use app::App;
|
||||
|
||||
/// Produces a string from a given list of possible values which is similar to
|
||||
/// the passed in value `v` with a certain confidence.
|
||||
|
@ -42,14 +42,13 @@ where
|
|||
|
||||
/// Returns a suffix that can be empty, or is the standard 'did you mean' phrase
|
||||
#[cfg_attr(feature = "lints", allow(needless_lifetimes))]
|
||||
pub fn did_you_mean_flag_suffix<'z, T, I>(
|
||||
pub fn did_you_mean_flag_suffix<'z, I>(
|
||||
arg: &str,
|
||||
longs: I,
|
||||
subcommands: &'z [App],
|
||||
) -> (String, Option<&'z str>)
|
||||
where
|
||||
T: AsRef<str> + 'z,
|
||||
I: IntoIterator<Item = &'z T>,
|
||||
I: IntoIterator<Item = &'z str>,
|
||||
{
|
||||
match did_you_mean(arg, longs) {
|
||||
Some(candidate) => {
|
||||
|
@ -61,14 +60,9 @@ where
|
|||
return (suffix, Some(candidate));
|
||||
}
|
||||
None => for subcommand in subcommands {
|
||||
let opts = subcommand
|
||||
.p
|
||||
.flags
|
||||
.iter()
|
||||
.filter_map(|f| f.s.long)
|
||||
.chain(subcommand.p.opts.iter().filter_map(|o| o.s.long));
|
||||
let longs = longs!(subcommand);
|
||||
|
||||
if let Some(candidate) = did_you_mean(arg, opts) {
|
||||
if let Some(candidate) = did_you_mean(arg, longs) {
|
||||
let suffix = format!(
|
||||
"\n\tDid you mean to put '{}{}' after the subcommand '{}'?",
|
||||
Format::Good("--"),
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
extern crate clap;
|
||||
extern crate regex;
|
||||
|
||||
use clap::{App, Arg, SubCommand, AppSettings, ErrorKind};
|
||||
use clap::{App, AppSettings, Arg, ErrorKind, Propagation, SubCommand};
|
||||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
|
@ -77,9 +77,7 @@ ARGS:
|
|||
fn sub_command_negate_required() {
|
||||
App::new("sub_command_negate")
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg(Arg::with_name("test")
|
||||
.required(true)
|
||||
.index(1))
|
||||
.arg(Arg::with_name("test").required(true).index(1))
|
||||
.subcommand(SubCommand::with_name("sub1"))
|
||||
.get_matches_from(vec!["myprog", "sub1"]);
|
||||
}
|
||||
|
@ -90,17 +88,15 @@ fn global_version() {
|
|||
.setting(AppSettings::GlobalVersion)
|
||||
.version("1.1")
|
||||
.subcommand(SubCommand::with_name("sub1"));
|
||||
app.p.propagate_settings();
|
||||
assert_eq!(app.p.subcommands[0].p.meta.version, Some("1.1"));
|
||||
app._propagate(Propagation::NextLevel);
|
||||
assert_eq!(app.subcommands[0].version, Some("1.1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_command_negate_required_2() {
|
||||
let result = App::new("sub_command_negate")
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg(Arg::with_name("test")
|
||||
.required(true)
|
||||
.index(1))
|
||||
.arg(Arg::with_name("test").required(true).index(1))
|
||||
.subcommand(SubCommand::with_name("sub1"))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
|
@ -123,8 +119,7 @@ fn sub_command_required() {
|
|||
fn arg_required_else_help() {
|
||||
let result = App::new("arg_required")
|
||||
.setting(AppSettings::ArgRequiredElseHelp)
|
||||
.arg(Arg::with_name("test")
|
||||
.index(1))
|
||||
.arg(Arg::with_name("test").index(1))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -135,8 +130,7 @@ fn arg_required_else_help() {
|
|||
fn arg_required_else_help_over_reqs() {
|
||||
let result = App::new("arg_required")
|
||||
.setting(AppSettings::ArgRequiredElseHelp)
|
||||
.arg(Arg::with_name("test")
|
||||
.index(1).required(true))
|
||||
.arg(Arg::with_name("test").index(1).required(true))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -150,9 +144,7 @@ fn infer_subcommands_fail_no_args() {
|
|||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "te"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::UnrecognizedSubcommand);
|
||||
}
|
||||
|
@ -164,9 +156,7 @@ fn infer_subcommands_fail_no_args() {
|
|||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "te"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidSubcommand);
|
||||
}
|
||||
|
@ -178,9 +168,7 @@ fn infer_subcommands_fail_with_args() {
|
|||
.arg(Arg::with_name("some"))
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "t"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "t"]);
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
|
||||
assert_eq!(m.unwrap().value_of("some"), Some("t"));
|
||||
}
|
||||
|
@ -192,9 +180,7 @@ fn infer_subcommands_fail_with_args2() {
|
|||
.arg(Arg::with_name("some"))
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "te"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "te"]);
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
|
||||
assert_eq!(m.unwrap().value_of("some"), Some("te"));
|
||||
}
|
||||
|
@ -204,9 +190,7 @@ fn infer_subcommands_pass() {
|
|||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.get_matches_from(vec![
|
||||
"prog", "te"
|
||||
]);
|
||||
.get_matches_from(vec!["prog", "te"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
|
@ -216,9 +200,7 @@ fn infer_subcommands_pass_close() {
|
|||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from(vec![
|
||||
"prog", "tes"
|
||||
]);
|
||||
.get_matches_from(vec!["prog", "tes"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
|
@ -229,9 +211,7 @@ fn infer_subcommands_fail_suggestions() {
|
|||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "temps"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "temps"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidSubcommand);
|
||||
}
|
||||
|
@ -243,9 +223,7 @@ fn infer_subcommands_fail_suggestions() {
|
|||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(SubCommand::with_name("test"))
|
||||
.subcommand(SubCommand::with_name("temp"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "temps"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "temps"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::UnrecognizedSubcommand);
|
||||
}
|
||||
|
@ -254,9 +232,7 @@ fn infer_subcommands_fail_suggestions() {
|
|||
fn no_bin_name() {
|
||||
let result = App::new("arg_required")
|
||||
.setting(AppSettings::NoBinaryName)
|
||||
.arg(Arg::with_name("test")
|
||||
.required(true)
|
||||
.index(1))
|
||||
.arg(Arg::with_name("test").required(true).index(1))
|
||||
.get_matches_from_safe(vec!["testing"]);
|
||||
assert!(result.is_ok());
|
||||
let matches = result.unwrap();
|
||||
|
@ -271,11 +247,18 @@ fn unified_help() {
|
|||
.about("tests stuff")
|
||||
.version("1.3")
|
||||
.setting(AppSettings::UnifiedHelpMessage)
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
[arg1] 'some pos arg'
|
||||
--option [opt] 'some option'");
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
[arg1] 'some pos arg'
|
||||
--option [opt] 'some option'",
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", UNIFIED_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
UNIFIED_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -285,10 +268,17 @@ fn skip_possible_values() {
|
|||
.about("tests stuff")
|
||||
.version("1.3")
|
||||
.setting(AppSettings::HidePossibleValuesInHelp)
|
||||
.args(&[Arg::from_usage("-o, --opt [opt] 'some option'").possible_values(&["one", "two"]),
|
||||
Arg::from_usage("[arg1] 'some pos arg'").possible_values(&["three", "four"])]);
|
||||
.args(&[
|
||||
Arg::from_usage("-o, --opt [opt] 'some option'").possible_values(&["one", "two"]),
|
||||
Arg::from_usage("[arg1] 'some pos arg'").possible_values(&["three", "four"]),
|
||||
]);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", SKIP_POS_VALS, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
SKIP_POS_VALS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -296,17 +286,15 @@ fn global_setting() {
|
|||
let mut app = App::new("test")
|
||||
.global_setting(AppSettings::ColoredHelp)
|
||||
.subcommand(SubCommand::with_name("subcmd"));
|
||||
app.p.propagate_settings();
|
||||
assert!(app.p
|
||||
.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.p
|
||||
.meta
|
||||
.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.p
|
||||
.is_set(AppSettings::ColoredHelp));
|
||||
app._propagate(Propagation::NextLevel);
|
||||
assert!(
|
||||
app.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.is_set(AppSettings::ColoredHelp)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -314,42 +302,42 @@ fn global_settings() {
|
|||
let mut app = App::new("test")
|
||||
.global_settings(&[AppSettings::ColoredHelp, AppSettings::TrailingVarArg])
|
||||
.subcommand(SubCommand::with_name("subcmd"));
|
||||
app.p.propagate_settings();
|
||||
assert!(app.p
|
||||
.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.p
|
||||
.meta
|
||||
.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.p
|
||||
.is_set(AppSettings::ColoredHelp));
|
||||
assert!(app.p
|
||||
.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.p
|
||||
.meta
|
||||
.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.p
|
||||
.is_set(AppSettings::TrailingVarArg));
|
||||
|
||||
app._propagate(Propagation::NextLevel);
|
||||
assert!(
|
||||
app.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.is_set(AppSettings::ColoredHelp)
|
||||
);
|
||||
assert!(
|
||||
app.subcommands
|
||||
.iter()
|
||||
.filter(|s| s.name == "subcmd")
|
||||
.next()
|
||||
.unwrap()
|
||||
.is_set(AppSettings::TrailingVarArg)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stop_delim_values_only_pos_follows() {
|
||||
let r = App::new("onlypos")
|
||||
.setting(AppSettings::DontDelimitTrailingValues)
|
||||
.args(&[Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--", "-f", "-g,x"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert!(!m.is_present("f"));
|
||||
assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), &["-f", "-g,x"]);
|
||||
assert_eq!(
|
||||
m.values_of("arg").unwrap().collect::<Vec<_>>(),
|
||||
&["-f", "-g,x"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -357,62 +345,75 @@ fn dont_delim_values_trailingvararg() {
|
|||
let m = App::new("positional")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.setting(AppSettings::DontDelimitTrailingValues)
|
||||
.arg(
|
||||
Arg::from_usage("[opt]... 'some pos'"),
|
||||
)
|
||||
.arg(Arg::from_usage("[opt]... 'some pos'"))
|
||||
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["test", "--foo", "-Wl,-bar"]);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["test", "--foo", "-Wl,-bar"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delim_values_only_pos_follows() {
|
||||
let r = App::new("onlypos")
|
||||
.args(&[Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--", "-f", "-g,x"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert!(!m.is_present("f"));
|
||||
assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), &["-f", "-g,x"]);
|
||||
assert_eq!(
|
||||
m.values_of("arg").unwrap().collect::<Vec<_>>(),
|
||||
&["-f", "-g,x"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delim_values_trailingvararg() {
|
||||
let m = App::new("positional")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
Arg::from_usage("[opt]... 'some pos'"),
|
||||
)
|
||||
.arg(Arg::from_usage("[opt]... 'some pos'"))
|
||||
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["test", "--foo", "-Wl,-bar"]);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["test", "--foo", "-Wl,-bar"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delim_values_only_pos_follows_with_delim() {
|
||||
let r = App::new("onlypos")
|
||||
.args(&[Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'").use_delimiter(true)])
|
||||
.args(&[
|
||||
Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg]... 'some arg'").use_delimiter(true),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--", "-f", "-g,x"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert!(!m.is_present("f"));
|
||||
assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), &["-f", "-g", "x"]);
|
||||
assert_eq!(
|
||||
m.values_of("arg").unwrap().collect::<Vec<_>>(),
|
||||
&["-f", "-g", "x"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delim_values_trailingvararg_with_delim() {
|
||||
let m = App::new("positional")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
Arg::from_usage("[opt]... 'some pos'").use_delimiter(true),
|
||||
)
|
||||
.arg(Arg::from_usage("[opt]... 'some pos'").use_delimiter(true))
|
||||
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["test", "--foo", "-Wl", "-bar"]);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["test", "--foo", "-Wl", "-bar"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -420,8 +421,7 @@ fn leading_hyphen_short() {
|
|||
let res = App::new("leadhy")
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.arg(Arg::with_name("some"))
|
||||
.arg(Arg::with_name("other")
|
||||
.short("o"))
|
||||
.arg(Arg::with_name("other").short("o"))
|
||||
.get_matches_from_safe(vec!["", "-bar", "-o"]);
|
||||
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
|
@ -435,8 +435,7 @@ fn leading_hyphen_long() {
|
|||
let res = App::new("leadhy")
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.arg(Arg::with_name("some"))
|
||||
.arg(Arg::with_name("other")
|
||||
.short("o"))
|
||||
.arg(Arg::with_name("other").short("o"))
|
||||
.get_matches_from_safe(vec!["", "--bar", "-o"]);
|
||||
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
|
@ -449,11 +448,8 @@ fn leading_hyphen_long() {
|
|||
fn leading_hyphen_opt() {
|
||||
let res = App::new("leadhy")
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.arg(Arg::with_name("some")
|
||||
.takes_value(true)
|
||||
.long("opt"))
|
||||
.arg(Arg::with_name("other")
|
||||
.short("o"))
|
||||
.arg(Arg::with_name("some").takes_value(true).long("opt"))
|
||||
.arg(Arg::with_name("other").short("o"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "--bar", "-o"]);
|
||||
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
|
@ -467,9 +463,7 @@ fn allow_negative_numbers() {
|
|||
let res = App::new("negnum")
|
||||
.setting(AppSettings::AllowNegativeNumbers)
|
||||
.arg(Arg::with_name("panum"))
|
||||
.arg(Arg::with_name("onum")
|
||||
.short("o")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("onum").short("o").takes_value(true))
|
||||
.get_matches_from_safe(vec!["negnum", "-20", "-o", "-1.2"]);
|
||||
assert!(res.is_ok(), "Error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
|
@ -482,9 +476,7 @@ fn allow_negative_numbers_fail() {
|
|||
let res = App::new("negnum")
|
||||
.setting(AppSettings::AllowNegativeNumbers)
|
||||
.arg(Arg::with_name("panum"))
|
||||
.arg(Arg::with_name("onum")
|
||||
.short("o")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("onum").short("o").takes_value(true))
|
||||
.get_matches_from_safe(vec!["negnum", "--foo", "-o", "-1.2"]);
|
||||
assert!(res.is_err());
|
||||
assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument)
|
||||
|
@ -495,33 +487,33 @@ fn leading_double_hyphen_trailingvararg() {
|
|||
let m = App::new("positional")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.setting(AppSettings::AllowLeadingHyphen)
|
||||
.arg(
|
||||
Arg::from_usage("[opt]... 'some pos'"),
|
||||
)
|
||||
.arg(Arg::from_usage("[opt]... 'some pos'"))
|
||||
.get_matches_from(vec!["", "--foo", "-Wl", "bar"]);
|
||||
assert!(m.is_present("opt"));
|
||||
assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["--foo", "-Wl", "bar"]);
|
||||
assert_eq!(
|
||||
m.values_of("opt").unwrap().collect::<Vec<_>>(),
|
||||
&["--foo", "-Wl", "bar"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unset_setting() {
|
||||
fn unset_setting() {
|
||||
let m = App::new("unset_setting");
|
||||
assert!(m.p.is_set(AppSettings::AllowInvalidUtf8));
|
||||
assert!(m.is_set(AppSettings::AllowInvalidUtf8));
|
||||
|
||||
let m = m.unset_setting(AppSettings::AllowInvalidUtf8);
|
||||
assert!(!m.p.is_set(AppSettings::AllowInvalidUtf8));
|
||||
assert!(!m.is_set(AppSettings::AllowInvalidUtf8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unset_settings() {
|
||||
fn unset_settings() {
|
||||
let m = App::new("unset_settings");
|
||||
assert!(&m.p.is_set(AppSettings::AllowInvalidUtf8));
|
||||
assert!(&m.p.is_set(AppSettings::ColorAuto));
|
||||
assert!(&m.is_set(AppSettings::AllowInvalidUtf8));
|
||||
assert!(&m.is_set(AppSettings::ColorAuto));
|
||||
|
||||
let m = m.unset_settings(&[AppSettings::AllowInvalidUtf8,
|
||||
AppSettings::ColorAuto]);
|
||||
assert!(!m.p.is_set(AppSettings::AllowInvalidUtf8));
|
||||
assert!(!m.p.is_set(AppSettings::ColorAuto));
|
||||
let m = m.unset_settings(&[AppSettings::AllowInvalidUtf8, AppSettings::ColorAuto]);
|
||||
assert!(!m.is_set(AppSettings::AllowInvalidUtf8), "{:?}", m.settings);
|
||||
assert!(!m.is_set(AppSettings::ColorAuto));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -545,38 +537,45 @@ fn dont_collapse_args() {
|
|||
Arg::with_name("arg2").help("some"),
|
||||
Arg::with_name("arg3").help("some"),
|
||||
]);
|
||||
assert!(test::compare_output(app, "clap-test --help", DONT_COLLAPSE_ARGS, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
DONT_COLLAPSE_ARGS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_eq() {
|
||||
let app = App::new("clap-test")
|
||||
.version("v1.4.8")
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
let app = App::new("clap-test").version("v1.4.8").arg(
|
||||
Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.required(true)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
.help("some"),
|
||||
);
|
||||
assert!(test::compare_output(app, "clap-test --help", REQUIRE_EQUALS, false));
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
REQUIRE_EQUALS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn args_negate_subcommands_one_level() {
|
||||
let res = App::new("disablehelp")
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg_from_usage("<arg1> 'some arg'")
|
||||
.arg_from_usage("<arg2> 'some arg'")
|
||||
.subcommand(SubCommand::with_name("sub1")
|
||||
.subcommand(SubCommand::with_name("sub2")
|
||||
.subcommand(SubCommand::with_name("sub3"))
|
||||
)
|
||||
)
|
||||
.get_matches_from_safe(vec!["", "pickles", "sub1"]);
|
||||
let res =
|
||||
App::new("disablehelp")
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg_from_usage("<arg1> 'some arg'")
|
||||
.arg_from_usage("<arg2> 'some arg'")
|
||||
.subcommand(SubCommand::with_name("sub1").subcommand(
|
||||
SubCommand::with_name("sub2").subcommand(SubCommand::with_name("sub3")),
|
||||
))
|
||||
.get_matches_from_safe(vec!["", "pickles", "sub1"]);
|
||||
assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
assert_eq!(m.value_of("arg2"), Some("sub1"));
|
||||
|
@ -589,20 +588,23 @@ fn args_negate_subcommands_two_levels() {
|
|||
.global_setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg_from_usage("<arg1> 'some arg'")
|
||||
.arg_from_usage("<arg2> 'some arg'")
|
||||
.subcommand(SubCommand::with_name("sub1")
|
||||
.arg_from_usage("<arg> 'some'")
|
||||
.arg_from_usage("<arg2> 'some'")
|
||||
.subcommand(SubCommand::with_name("sub2")
|
||||
.subcommand(SubCommand::with_name("sub3"))
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub1")
|
||||
.arg_from_usage("<arg> 'some'")
|
||||
.arg_from_usage("<arg2> 'some'")
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub2").subcommand(SubCommand::with_name("sub3")),
|
||||
),
|
||||
)
|
||||
.get_matches_from_safe(vec!["", "sub1", "arg", "sub2"]);
|
||||
assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind);
|
||||
let m = res.unwrap();
|
||||
assert_eq!(m.subcommand_matches("sub1").unwrap().value_of("arg2"), Some("sub2"));
|
||||
assert_eq!(
|
||||
m.subcommand_matches("sub1").unwrap().value_of("arg2"),
|
||||
Some("sub2")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn propagate_vals_down() {
|
||||
let m = App::new("myprog")
|
||||
|
@ -667,5 +669,10 @@ fn issue_1093_allow_ext_sc() {
|
|||
let app = App::new("clap-test")
|
||||
.version("v1.4.8")
|
||||
.setting(AppSettings::AllowExternalSubcommands);
|
||||
assert!(test::compare_output(app, "clap-test --help", ALLOW_EXT_SC, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
ALLOW_EXT_SC,
|
||||
false
|
||||
));
|
||||
}
|
|
@ -36,14 +36,14 @@ OPTIONS:
|
|||
#[test]
|
||||
fn single_alias_of_option() {
|
||||
let a = App::new("single_alias")
|
||||
.arg(Arg::with_name("alias")
|
||||
.long("alias")
|
||||
.takes_value(true)
|
||||
.help("single alias")
|
||||
.alias("new-opt"))
|
||||
.get_matches_from_safe(vec![
|
||||
"", "--new-opt", "cool"
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("alias")
|
||||
.long("alias")
|
||||
.takes_value(true)
|
||||
.help("single alias")
|
||||
.alias("new-opt"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["", "--new-opt", "cool"]);
|
||||
assert!(a.is_ok());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("alias"));
|
||||
|
@ -52,37 +52,30 @@ fn single_alias_of_option() {
|
|||
|
||||
#[test]
|
||||
fn multiple_aliases_of_option() {
|
||||
let a = App::new("multiple_aliases")
|
||||
.arg(Arg::with_name("aliases")
|
||||
let a = App::new("multiple_aliases").arg(
|
||||
Arg::with_name("aliases")
|
||||
.long("aliases")
|
||||
.takes_value(true)
|
||||
.help("multiple aliases")
|
||||
.aliases(&vec![
|
||||
"alias1",
|
||||
"alias2",
|
||||
"alias3"
|
||||
]));
|
||||
let long = a.clone().get_matches_from_safe(vec![
|
||||
"", "--aliases", "value"
|
||||
]);
|
||||
.aliases(&vec!["alias1", "alias2", "alias3"]),
|
||||
);
|
||||
let long = a.clone()
|
||||
.get_matches_from_safe(vec!["", "--aliases", "value"]);
|
||||
assert!(long.is_ok());
|
||||
let long = long.unwrap();
|
||||
|
||||
let als1 = a.clone().get_matches_from_safe(vec![
|
||||
"", "--alias1", "value"
|
||||
]);
|
||||
let als1 = a.clone()
|
||||
.get_matches_from_safe(vec!["", "--alias1", "value"]);
|
||||
assert!(als1.is_ok());
|
||||
let als1 = als1.unwrap();
|
||||
|
||||
let als2 = a.clone().get_matches_from_safe(vec![
|
||||
"", "--alias2", "value"
|
||||
]);
|
||||
let als2 = a.clone()
|
||||
.get_matches_from_safe(vec!["", "--alias2", "value"]);
|
||||
assert!(als2.is_ok());
|
||||
let als2 = als2.unwrap();
|
||||
|
||||
let als3 = a.clone().get_matches_from_safe(vec![
|
||||
"", "--alias3", "value"
|
||||
]);
|
||||
let als3 = a.clone()
|
||||
.get_matches_from_safe(vec!["", "--alias3", "value"]);
|
||||
assert!(als3.is_ok());
|
||||
let als3 = als3.unwrap();
|
||||
|
||||
|
@ -99,10 +92,8 @@ fn multiple_aliases_of_option() {
|
|||
#[test]
|
||||
fn single_alias_of_flag() {
|
||||
let a = App::new("test")
|
||||
.arg(Arg::with_name("flag")
|
||||
.long("flag")
|
||||
.alias("alias"))
|
||||
.get_matches_from_safe(vec!["", "--alias"]);
|
||||
.arg(Arg::with_name("flag").long("flag").alias("alias"))
|
||||
.get_matches_from_safe(vec!["", "--alias"]);
|
||||
assert!(a.is_ok());
|
||||
let a = a.unwrap();
|
||||
assert!(a.is_present("flag"));
|
||||
|
@ -110,12 +101,13 @@ fn single_alias_of_flag() {
|
|||
|
||||
#[test]
|
||||
fn multiple_aliases_of_flag() {
|
||||
let a = App::new("test")
|
||||
.arg(Arg::with_name("flag")
|
||||
.long("flag")
|
||||
.aliases(&["invisible",
|
||||
"set", "of",
|
||||
"cool", "aliases"]));
|
||||
let a = App::new("test").arg(Arg::with_name("flag").long("flag").aliases(&[
|
||||
"invisible",
|
||||
"set",
|
||||
"of",
|
||||
"cool",
|
||||
"aliases",
|
||||
]));
|
||||
|
||||
let flag = a.clone().get_matches_from_safe(vec!["", "--flag"]);
|
||||
assert!(flag.is_ok());
|
||||
|
@ -142,19 +134,22 @@ fn multiple_aliases_of_flag() {
|
|||
#[test]
|
||||
fn alias_on_a_subcommand_option() {
|
||||
let m = App::new("test")
|
||||
.subcommand(SubCommand::with_name("some")
|
||||
.arg(Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.alias("opt")
|
||||
.help("testing testing")))
|
||||
.arg(Arg::with_name("other")
|
||||
.long("other")
|
||||
.aliases(&vec!["o1", "o2", "o3"]))
|
||||
.get_matches_from(vec![
|
||||
"test", "some", "--opt", "awesome"
|
||||
]);
|
||||
.subcommand(
|
||||
SubCommand::with_name("some").arg(
|
||||
Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.alias("opt")
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("other")
|
||||
.long("other")
|
||||
.aliases(&vec!["o1", "o2", "o3"]),
|
||||
)
|
||||
.get_matches_from(vec!["test", "some", "--opt", "awesome"]);
|
||||
|
||||
assert!(m.subcommand_matches("some").is_some());
|
||||
let sub_m = m.subcommand_matches("some").unwrap();
|
||||
|
@ -164,37 +159,52 @@ fn alias_on_a_subcommand_option() {
|
|||
|
||||
#[test]
|
||||
fn invisible_arg_aliases_help_output() {
|
||||
let app = App::new("ct")
|
||||
.author("Salim Afiune")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
let app = App::new("ct").author("Salim Afiune").subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.takes_value(true)
|
||||
.aliases(&["invisible", "als1", "more"]))
|
||||
.arg(Arg::from_usage("-f, --flag")
|
||||
.aliases(&["invisible", "flg1", "anyway"])));
|
||||
assert!(test::compare_output(app, "ct test --help", SC_INVISIBLE_ALIAS_HELP, false));
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.takes_value(true)
|
||||
.aliases(&["invisible", "als1", "more"]),
|
||||
)
|
||||
.arg(Arg::from_usage("-f, --flag").aliases(&["invisible", "flg1", "anyway"])),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ct test --help",
|
||||
SC_INVISIBLE_ALIAS_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_arg_aliases_help_output() {
|
||||
let app = App::new("ct")
|
||||
.author("Salim Afiune")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
let app = App::new("ct").author("Salim Afiune").subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("Some help")
|
||||
.version("1.2")
|
||||
.arg(Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.takes_value(true)
|
||||
.alias("invisible")
|
||||
.visible_alias("visible"))
|
||||
.arg(Arg::with_name("flg")
|
||||
.long("flag")
|
||||
.short("f")
|
||||
.visible_aliases(&["v_flg", "flag2", "flg3"])));
|
||||
assert!(test::compare_output(app, "ct test --help", SC_VISIBLE_ALIAS_HELP, false));
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.takes_value(true)
|
||||
.alias("invisible")
|
||||
.visible_alias("visible"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("flg")
|
||||
.long("flag")
|
||||
.short("f")
|
||||
.visible_aliases(&["v_flg", "flag2", "flg3"]),
|
||||
),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ct test --help",
|
||||
SC_VISIBLE_ALIAS_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
|
|
@ -7,8 +7,14 @@ include!("../clap-test.rs");
|
|||
|
||||
#[test]
|
||||
fn borrowed_args() {
|
||||
let arg = Arg::with_name("some").short("s").long("some").help("other help");
|
||||
let arg2 = Arg::with_name("some2").short("S").long("some-thing").help("other help");
|
||||
let arg = Arg::with_name("some")
|
||||
.short("s")
|
||||
.long("some")
|
||||
.help("other help");
|
||||
let arg2 = Arg::with_name("some2")
|
||||
.short("S")
|
||||
.long("some-thing")
|
||||
.help("other help");
|
||||
let result = App::new("sub_command_negate")
|
||||
.arg(Arg::with_name("test").index(1))
|
||||
.arg(&arg)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
extern crate regex;
|
||||
extern crate clap;
|
||||
extern crate regex;
|
||||
|
||||
use clap::{App, Arg, SubCommand, Shell};
|
||||
use clap::{App, Arg, Shell, SubCommand};
|
||||
use regex::Regex;
|
||||
|
||||
static BASH: &'static str = r#"_myapp() {
|
||||
|
@ -63,7 +63,7 @@ static BASH: &'static str = r#"_myapp() {
|
|||
return 0
|
||||
;;
|
||||
myapp__test)
|
||||
opts=" -h -V --help --version --case "
|
||||
opts=" -h -V --case --help --version "
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
@ -189,7 +189,8 @@ complete -c myapp -n "__fish_using_command myapp help" -s h -l help -d 'Prints h
|
|||
complete -c myapp -n "__fish_using_command myapp help" -s V -l version -d 'Prints version information'
|
||||
"#;
|
||||
|
||||
#[cfg(not(target_os="windows"))]
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
static POWERSHELL: &'static str = r#"
|
||||
@('myapp', './myapp') | %{
|
||||
Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock {
|
||||
|
@ -240,7 +241,8 @@ static POWERSHELL: &'static str = r#"
|
|||
}
|
||||
"#;
|
||||
|
||||
#[cfg(target_os="windows")]
|
||||
#[cfg_attr(target_os = "windows", allow(dead_code))]
|
||||
#[cfg(target_os = "windows")]
|
||||
static POWERSHELL: &'static str = r#"
|
||||
@('myapp', './myapp', 'myapp.exe', '.\myapp', '.\myapp.exe', './myapp.exe') | %{
|
||||
Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock {
|
||||
|
@ -280,7 +282,8 @@ static POWERSHELL: &'static str = r#"
|
|||
}
|
||||
"#;
|
||||
|
||||
#[cfg(not(target_os="windows"))]
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
static POWERSHELL_SPECIAL_CMDS: &'static str = r#"
|
||||
@('my_app', './my_app') | %{
|
||||
Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock {
|
||||
|
@ -340,7 +343,8 @@ static POWERSHELL_SPECIAL_CMDS: &'static str = r#"
|
|||
}
|
||||
"#;
|
||||
|
||||
#[cfg(target_os="windows")]
|
||||
#[cfg_attr(target_os = "windows", allow(dead_code))]
|
||||
#[cfg(target_os = "windows")]
|
||||
static POWERSHELL_SPECIAL_CMDS: &'static str = r#"
|
||||
@('my_app', './my_app', 'my_app.exe', '.\my_app', '.\my_app.exe', './my_app.exe') | %{
|
||||
Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock {
|
||||
|
@ -609,7 +613,7 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
|
|||
return 0
|
||||
;;
|
||||
my_app__some_cmd)
|
||||
opts=" -h -V --help --version --config "
|
||||
opts=" -h -V --config --help --version "
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
@ -628,7 +632,7 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
|
|||
return 0
|
||||
;;
|
||||
my_app__test)
|
||||
opts=" -h -V --help --version --case "
|
||||
opts=" -h -V --case --help --version "
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
|
@ -738,45 +742,63 @@ fn build_app_with_name(s: &'static str) -> App<'static, 'static> {
|
|||
App::new(s)
|
||||
.about("Tests completions")
|
||||
.arg(Arg::with_name("file").help("some input file"))
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("tests things")
|
||||
.arg(Arg::with_name("case")
|
||||
.long("case")
|
||||
.takes_value(true)
|
||||
.help("the case to test")))
|
||||
.subcommand(
|
||||
SubCommand::with_name("test").about("tests things").arg(
|
||||
Arg::with_name("case")
|
||||
.long("case")
|
||||
.takes_value(true)
|
||||
.help("the case to test"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn build_app_special_commands() -> App<'static, 'static> {
|
||||
build_app_with_name("my_app")
|
||||
.subcommand(SubCommand::with_name("some_cmd")
|
||||
.about("tests other things")
|
||||
.arg(Arg::with_name("config")
|
||||
.long("--config")
|
||||
.takes_value(true)
|
||||
.help("the other case to test")))
|
||||
.subcommand(
|
||||
SubCommand::with_name("some_cmd")
|
||||
.about("tests other things")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.long("--config")
|
||||
.takes_value(true)
|
||||
.help("the other case to test"),
|
||||
),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("some-cmd-with-hypens"))
|
||||
}
|
||||
|
||||
fn build_app_special_help() -> App<'static, 'static> {
|
||||
App::new("my_app")
|
||||
.arg(Arg::with_name("single-quotes")
|
||||
.long("single-quotes")
|
||||
.help("Can be 'always', 'auto', or 'never'"))
|
||||
.arg(Arg::with_name("double-quotes")
|
||||
.long("double-quotes")
|
||||
.help("Can be \"always\", \"auto\", or \"never\""))
|
||||
.arg(Arg::with_name("backticks")
|
||||
.long("backticks")
|
||||
.help("For more information see `echo test`"))
|
||||
.arg(Arg::with_name("backslash")
|
||||
.long("backslash")
|
||||
.help("Avoid '\\n'"))
|
||||
.arg(Arg::with_name("brackets")
|
||||
.long("brackets")
|
||||
.help("List packages [filter]"))
|
||||
.arg(Arg::with_name("expansions")
|
||||
.long("expansions")
|
||||
.help("Execute the shell command with $SHELL"))
|
||||
.arg(
|
||||
Arg::with_name("single-quotes")
|
||||
.long("single-quotes")
|
||||
.help("Can be 'always', 'auto', or 'never'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("double-quotes")
|
||||
.long("double-quotes")
|
||||
.help("Can be \"always\", \"auto\", or \"never\""),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("backticks")
|
||||
.long("backticks")
|
||||
.help("For more information see `echo test`"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("backslash")
|
||||
.long("backslash")
|
||||
.help("Avoid '\\n'"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("brackets")
|
||||
.long("brackets")
|
||||
.help("List packages [filter]"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("expansions")
|
||||
.long("expansions")
|
||||
.help("Execute the shell command with $SHELL"),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -3,7 +3,7 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, Arg, ErrorKind, ArgGroup};
|
||||
use clap::{App, Arg, ArgGroup, ErrorKind};
|
||||
|
||||
static CONFLICT_ERR: &'static str = "error: The argument '-F' cannot be used with '--flag'
|
||||
|
||||
|
@ -22,8 +22,7 @@ For more information try --help";
|
|||
#[test]
|
||||
fn flag_conflict() {
|
||||
let result = App::new("flag_conflict")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("other"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("other"))
|
||||
.arg(Arg::from_usage("-o, --other 'some flag'"))
|
||||
.get_matches_from_safe(vec!["myprog", "-f", "-o"]);
|
||||
assert!(result.is_err());
|
||||
|
@ -34,8 +33,7 @@ fn flag_conflict() {
|
|||
#[test]
|
||||
fn flag_conflict_2() {
|
||||
let result = App::new("flag_conflict")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("other"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("other"))
|
||||
.arg(Arg::from_usage("-o, --other 'some flag'"))
|
||||
.get_matches_from_safe(vec!["myprog", "-o", "-f"]);
|
||||
assert!(result.is_err());
|
||||
|
@ -46,12 +44,13 @@ fn flag_conflict_2() {
|
|||
#[test]
|
||||
fn group_conflict() {
|
||||
let result = App::new("group_conflict")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("gr"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("gr"))
|
||||
.group(
|
||||
ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"),
|
||||
)
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from_safe(vec!["myprog", "--other", "-f"]);
|
||||
|
@ -63,12 +62,13 @@ fn group_conflict() {
|
|||
#[test]
|
||||
fn group_conflict_2() {
|
||||
let result = App::new("group_conflict")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("gr"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("gr"))
|
||||
.group(
|
||||
ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"),
|
||||
)
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from_safe(vec!["myprog", "-f", "--some"]);
|
||||
|
@ -79,21 +79,29 @@ fn group_conflict_2() {
|
|||
|
||||
#[test]
|
||||
fn conflict_output() {
|
||||
test::compare_output(test::complex_app(), "clap-test val1 --flag --long-option-2 val2 -F", CONFLICT_ERR, true);
|
||||
test::compare_output(
|
||||
test::complex_app(),
|
||||
"clap-test val1 --flag --long-option-2 val2 -F",
|
||||
CONFLICT_ERR,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_output_rev() {
|
||||
test::compare_output(test::complex_app(), "clap-test val1 -F --long-option-2 val2 --flag", CONFLICT_ERR_REV, true);
|
||||
test::compare_output(
|
||||
test::complex_app(),
|
||||
"clap-test val1 -F --long-option-2 val2 --flag",
|
||||
CONFLICT_ERR_REV,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conflict_with_unused_default_value() {
|
||||
let result = App::new("conflict")
|
||||
.arg(Arg::from_usage("-o, --opt=[opt] 'some opt'")
|
||||
.default_value("default"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("opt"))
|
||||
.arg(Arg::from_usage("-o, --opt=[opt] 'some opt'").default_value("default"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("opt"))
|
||||
.get_matches_from_safe(vec!["myprog", "-f"]);
|
||||
assert!(result.is_ok());
|
||||
let m = result.unwrap();
|
||||
|
|
|
@ -8,9 +8,7 @@ use clap::{App, Arg, ErrorKind};
|
|||
#[test]
|
||||
fn opts() {
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("-o [opt] 'some opt'").default_value("default"),
|
||||
)
|
||||
.arg(Arg::from_usage("-o [opt] 'some opt'").default_value("default"))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -21,9 +19,7 @@ fn opts() {
|
|||
#[test]
|
||||
fn opt_user_override() {
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("--opt [FILE] 'some arg'").default_value("default"),
|
||||
)
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'").default_value("default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -61,9 +57,7 @@ fn osstr_opts() {
|
|||
let expected = OsStr::new("default");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("-o [opt] 'some opt'").default_value_os(expected),
|
||||
)
|
||||
.arg(Arg::from_usage("-o [opt] 'some opt'").default_value_os(expected))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -77,9 +71,7 @@ fn osstr_opt_user_override() {
|
|||
let default = OsStr::new("default");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("--opt [FILE] 'some arg'").default_value_os(default),
|
||||
)
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'").default_value_os(default))
|
||||
.get_matches_from_safe(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -93,9 +85,7 @@ fn osstr_positionals() {
|
|||
let expected = OsStr::new("default");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("[arg] 'some opt'").default_value_os(expected),
|
||||
)
|
||||
.arg(Arg::from_usage("[arg] 'some opt'").default_value_os(expected))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -109,9 +99,7 @@ fn osstr_positional_user_override() {
|
|||
let default = OsStr::new("default");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("[arg] 'some arg'").default_value_os(default),
|
||||
)
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_os(default))
|
||||
.get_matches_from_safe(vec!["", "value"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -125,11 +113,7 @@ fn osstr_positional_user_override() {
|
|||
fn default_if_arg_present_no_default() {
|
||||
let r = App::new("df")
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'"))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if(
|
||||
"opt",
|
||||
None,
|
||||
"default",
|
||||
))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if("opt", None, "default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "some"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -141,11 +125,7 @@ fn default_if_arg_present_no_default() {
|
|||
fn default_if_arg_present_no_default_user_override() {
|
||||
let r = App::new("df")
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'"))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if(
|
||||
"opt",
|
||||
None,
|
||||
"default",
|
||||
))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if("opt", None, "default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -223,11 +203,7 @@ fn default_if_arg_present_no_arg_with_default_user_override() {
|
|||
fn default_if_arg_present_with_value_no_default() {
|
||||
let r = App::new("df")
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'"))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if(
|
||||
"opt",
|
||||
Some("value"),
|
||||
"default",
|
||||
))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if("opt", Some("value"), "default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "value"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -239,11 +215,7 @@ fn default_if_arg_present_with_value_no_default() {
|
|||
fn default_if_arg_present_with_value_no_default_fail() {
|
||||
let r = App::new("df")
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'"))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if(
|
||||
"opt",
|
||||
Some("value"),
|
||||
"default",
|
||||
))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if("opt", Some("value"), "default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -255,11 +227,7 @@ fn default_if_arg_present_with_value_no_default_fail() {
|
|||
fn default_if_arg_present_with_value_no_default_user_override() {
|
||||
let r = App::new("df")
|
||||
.arg(Arg::from_usage("--opt [FILE] 'some arg'"))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if(
|
||||
"opt",
|
||||
Some("some"),
|
||||
"default",
|
||||
))
|
||||
.arg(Arg::from_usage("[arg] 'some arg'").default_value_if("opt", Some("some"), "default"))
|
||||
.get_matches_from_safe(vec!["", "--opt", "some", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
|
|
@ -5,13 +5,8 @@ use clap::{App, Arg};
|
|||
#[test]
|
||||
fn opt_default_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.long("option")
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"--option", "val1,val2,val3",
|
||||
]);
|
||||
.arg(Arg::with_name("option").long("option").takes_value(true))
|
||||
.get_matches_from_safe(vec!["", "--option", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
let m = m.unwrap();
|
||||
|
@ -24,13 +19,8 @@ fn opt_default_no_delim() {
|
|||
#[test]
|
||||
fn opt_eq_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.long("option")
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"--option=val1,val2,val3",
|
||||
]);
|
||||
.arg(Arg::with_name("option").long("option").takes_value(true))
|
||||
.get_matches_from_safe(vec!["", "--option=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
let m = m.unwrap();
|
||||
|
@ -43,13 +33,8 @@ fn opt_eq_no_delim() {
|
|||
#[test]
|
||||
fn opt_s_eq_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.short("o")
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"-o=val1,val2,val3",
|
||||
]);
|
||||
.arg(Arg::with_name("option").short("o").takes_value(true))
|
||||
.get_matches_from_safe(vec!["", "-o=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
@ -62,13 +47,8 @@ fn opt_s_eq_no_delim() {
|
|||
#[test]
|
||||
fn opt_s_default_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.short("o")
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"-o", "val1,val2,val3",
|
||||
]);
|
||||
.arg(Arg::with_name("option").short("o").takes_value(true))
|
||||
.get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok(), "{:?}", m.unwrap_err());
|
||||
let m = m.unwrap();
|
||||
|
@ -81,13 +61,8 @@ fn opt_s_default_no_delim() {
|
|||
#[test]
|
||||
fn opt_s_no_space_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.short("o")
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"-o", "val1,val2,val3",
|
||||
]);
|
||||
.arg(Arg::with_name("option").short("o").takes_value(true))
|
||||
.get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
let m = m.unwrap();
|
||||
|
@ -100,14 +75,13 @@ fn opt_s_no_space_no_delim() {
|
|||
#[test]
|
||||
fn opt_s_no_space_mult_no_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.short("o")
|
||||
.multiple(true)
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"-o", "val1,val2,val3",
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("option")
|
||||
.short("o")
|
||||
.multiple(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
let m = m.unwrap();
|
||||
|
@ -120,20 +94,22 @@ fn opt_s_no_space_mult_no_delim() {
|
|||
#[test]
|
||||
fn opt_eq_mult_def_delim() {
|
||||
let m = App::new("no_delim")
|
||||
.arg(Arg::with_name("option")
|
||||
.long("opt")
|
||||
.multiple(true)
|
||||
.use_delimiter(true)
|
||||
.takes_value(true))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"--opt=val1,val2,val3",
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("option")
|
||||
.long("opt")
|
||||
.multiple(true)
|
||||
.use_delimiter(true)
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches_from_safe(vec!["", "--opt=val1,val2,val3"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
let m = m.unwrap();
|
||||
|
||||
assert!(m.is_present("option"));
|
||||
assert_eq!(m.occurrences_of("option"), 1);
|
||||
assert_eq!(m.values_of("option").unwrap().collect::<Vec<_>>(), &["val1", "val2", "val3"]);
|
||||
assert_eq!(
|
||||
m.values_of("option").unwrap().collect::<Vec<_>>(),
|
||||
&["val1", "val2", "val3"]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ extern crate regex;
|
|||
|
||||
use std::str;
|
||||
|
||||
use clap::{App, Arg, SubCommand, AppSettings};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
|
@ -119,16 +119,25 @@ OPTIONS:
|
|||
|
||||
#[test]
|
||||
fn no_derive_order() {
|
||||
let app = App::new("test")
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
]);
|
||||
let app = App::new("test").version("1.2").args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", NO_DERIVE_ORDER, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
NO_DERIVE_ORDER,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -138,12 +147,23 @@ fn derive_order() {
|
|||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", DERIVE_ORDER, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
DERIVE_ORDER,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -153,12 +173,23 @@ fn unified_help() {
|
|||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", UNIFIED_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
UNIFIED_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -169,12 +200,23 @@ fn unified_help_and_derive_order() {
|
|||
.version("1.2")
|
||||
.args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", UNIFIED_HELP_AND_DERIVE, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
UNIFIED_HELP_AND_DERIVE,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -182,32 +224,54 @@ fn derive_order_subcommand_propagate() {
|
|||
let app = App::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.version("1.2")
|
||||
.subcommand(SubCommand::with_name("sub")
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub").version("1.2").args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
]));
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test sub --help", DERIVE_ORDER_SC_PROP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test sub --help",
|
||||
DERIVE_ORDER_SC_PROP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unified_help_subcommand_propagate() {
|
||||
let app = App::new("test")
|
||||
.global_setting(AppSettings::UnifiedHelpMessage)
|
||||
.subcommand(SubCommand::with_name("sub")
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub").version("1.2").args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
]));
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test sub --help", UNIFIED_SC_PROP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test sub --help",
|
||||
UNIFIED_SC_PROP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -215,16 +279,27 @@ fn unified_help_and_derive_order_subcommand_propagate() {
|
|||
let app = App::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.global_setting(AppSettings::UnifiedHelpMessage)
|
||||
.subcommand(SubCommand::with_name("sub")
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub").version("1.2").args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag"),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
]));
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test sub --help", UNIFIED_DERIVE_SC_PROP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test sub --help",
|
||||
UNIFIED_DERIVE_SC_PROP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -232,14 +307,28 @@ fn unified_help_and_derive_order_subcommand_propagate_with_explicit_display_orde
|
|||
let app = App::new("test")
|
||||
.global_setting(AppSettings::DeriveDisplayOrder)
|
||||
.global_setting(AppSettings::UnifiedHelpMessage)
|
||||
.subcommand(SubCommand::with_name("sub")
|
||||
.version("1.2")
|
||||
.args(&[
|
||||
.subcommand(
|
||||
SubCommand::with_name("sub").version("1.2").args(&[
|
||||
Arg::with_name("flag_b").long("flag_b").help("first flag"),
|
||||
Arg::with_name("option_b").long("option_b").takes_value(true).help("first option"),
|
||||
Arg::with_name("flag_a").long("flag_a").help("second flag").display_order(0),
|
||||
Arg::with_name("option_a").long("option_a").takes_value(true).help("second option"),
|
||||
]));
|
||||
Arg::with_name("option_b")
|
||||
.long("option_b")
|
||||
.takes_value(true)
|
||||
.help("first option"),
|
||||
Arg::with_name("flag_a")
|
||||
.long("flag_a")
|
||||
.help("second flag")
|
||||
.display_order(0),
|
||||
Arg::with_name("option_a")
|
||||
.long("option_a")
|
||||
.takes_value(true)
|
||||
.help("second option"),
|
||||
]),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test sub --help", UNIFIED_DERIVE_SC_PROP_EXPLICIT_ORDER, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test sub --help",
|
||||
UNIFIED_DERIVE_SC_PROP_EXPLICIT_ORDER,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
|
29
tests/env.rs
29
tests/env.rs
|
@ -25,9 +25,7 @@ fn env_os() {
|
|||
env::set_var("CLP_TEST_ENV", "env");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("[arg] 'some opt'").env_os(OsStr::new("CLP_TEST_ENV")),
|
||||
)
|
||||
.arg(Arg::from_usage("[arg] 'some opt'").env_os(OsStr::new("CLP_TEST_ENV")))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
|
||||
assert!(r.is_ok());
|
||||
|
@ -78,9 +76,7 @@ fn opt_user_override() {
|
|||
env::set_var("CLP_TEST_ENV", "env");
|
||||
|
||||
let r = App::new("df")
|
||||
.arg(
|
||||
Arg::from_usage("--arg [FILE] 'some arg'").env("CLP_TEST_ENV"),
|
||||
)
|
||||
.arg(Arg::from_usage("--arg [FILE] 'some arg'").env("CLP_TEST_ENV"))
|
||||
.get_matches_from_safe(vec!["", "--arg", "opt"]);
|
||||
|
||||
assert!(r.is_ok());
|
||||
|
@ -204,7 +200,6 @@ fn possible_value() {
|
|||
assert_eq!(m.value_of("arg").unwrap(), "env");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn not_possible_value() {
|
||||
env::set_var("CLP_TEST_ENV", "env");
|
||||
|
@ -228,10 +223,12 @@ fn validator() {
|
|||
.arg(
|
||||
Arg::from_usage("[arg] 'some opt'")
|
||||
.env("CLP_TEST_ENV")
|
||||
.validator(|s| if s == "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("not equal".to_string())
|
||||
.validator(|s| {
|
||||
if s == "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("not equal".to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
.get_matches_from_safe(vec![""]);
|
||||
|
@ -251,10 +248,12 @@ fn validator_invalid() {
|
|||
.arg(
|
||||
Arg::from_usage("[arg] 'some opt'")
|
||||
.env("CLP_TEST_ENV")
|
||||
.validator(|s| if s != "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("is equal".to_string())
|
||||
.validator(|s| {
|
||||
if s != "env" {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("is equal".to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
.get_matches_from_safe(vec![""]);
|
||||
|
|
111
tests/flags.rs
111
tests/flags.rs
|
@ -7,8 +7,8 @@ fn flag_using_short() {
|
|||
let m = App::new("flag")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::from_usage("-c, --color 'some other flag'")
|
||||
])
|
||||
Arg::from_usage("-c, --color 'some other flag'"),
|
||||
])
|
||||
.get_matches_from(vec!["", "-f", "-c"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
@ -17,38 +17,31 @@ fn flag_using_short() {
|
|||
#[test]
|
||||
fn lots_o_flags_sep() {
|
||||
let r = App::new("opts")
|
||||
.arg(
|
||||
Arg::from_usage("-o... 'some flag'"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
]);
|
||||
.arg(Arg::from_usage("-o... 'some flag'"))
|
||||
.get_matches_from_safe(vec![
|
||||
"", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
|
||||
"-o", "-o", "-o",
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
|
@ -58,16 +51,15 @@ fn lots_o_flags_sep() {
|
|||
#[test]
|
||||
fn lots_o_flags_combined() {
|
||||
let r = App::new("opts")
|
||||
.arg(
|
||||
Arg::from_usage("-o... 'some flag'"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["",
|
||||
.arg(Arg::from_usage("-o... 'some flag'"))
|
||||
.get_matches_from_safe(vec![
|
||||
"",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
|
||||
"-ooooooooooooooooooooooooooooooooooooooooo",
|
||||
]);
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
|
@ -79,8 +71,8 @@ fn flag_using_long() {
|
|||
let m = App::new("flag")
|
||||
.args(&[
|
||||
Arg::from_usage("--flag 'some flag'"),
|
||||
Arg::from_usage("--color 'some other flag'")
|
||||
])
|
||||
Arg::from_usage("--color 'some other flag'"),
|
||||
])
|
||||
.get_matches_from(vec!["", "--flag", "--color"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
@ -91,8 +83,8 @@ fn flag_using_mixed() {
|
|||
let m = App::new("flag")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::from_usage("-c, --color 'some other flag'")
|
||||
])
|
||||
Arg::from_usage("-c, --color 'some other flag'"),
|
||||
])
|
||||
.get_matches_from(vec!["", "-f", "--color"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
@ -100,8 +92,8 @@ fn flag_using_mixed() {
|
|||
let m = App::new("flag")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::from_usage("-c, --color 'some other flag'")
|
||||
])
|
||||
Arg::from_usage("-c, --color 'some other flag'"),
|
||||
])
|
||||
.get_matches_from(vec!["", "--flag", "-c"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
@ -113,8 +105,8 @@ fn multiple_flags_in_single() {
|
|||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::from_usage("-c, --color 'some other flag'"),
|
||||
Arg::from_usage("-d, --debug 'another other flag'")
|
||||
])
|
||||
Arg::from_usage("-d, --debug 'another other flag'"),
|
||||
])
|
||||
.get_matches_from(vec!["", "-fcd"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert!(m.is_present("color"));
|
||||
|
@ -124,24 +116,23 @@ fn multiple_flags_in_single() {
|
|||
#[test]
|
||||
fn short_flag_misspel() {
|
||||
let a = Arg::from_usage("-f1, --flag 'some flag'");
|
||||
assert_eq!(a.b.name, "flag");
|
||||
assert_eq!(a.s.short.unwrap(), 'f');
|
||||
assert_eq!(a.s.long.unwrap(), "flag");
|
||||
assert_eq!(a.b.help.unwrap(), "some flag");
|
||||
assert_eq!(a.name, "flag");
|
||||
assert_eq!(a.short.unwrap(), 'f');
|
||||
assert_eq!(a.long.unwrap(), "flag");
|
||||
assert_eq!(a.help.unwrap(), "some flag");
|
||||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.v.val_names.is_none());
|
||||
assert!(a.v.num_vals.is_none());
|
||||
assert!(a.val_names.is_none());
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_flag_name_missing() {
|
||||
let a = Arg::from_usage("-f 'some flag'");
|
||||
assert_eq!(a.b.name, "f");
|
||||
assert_eq!(a.s.short.unwrap(), 'f');
|
||||
assert!(a.s.long.is_none());
|
||||
assert_eq!(a.b.help.unwrap(), "some flag");
|
||||
assert_eq!(a.name, "f");
|
||||
assert_eq!(a.short.unwrap(), 'f');
|
||||
assert!(a.long.is_none());
|
||||
assert_eq!(a.help.unwrap(), "some flag");
|
||||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.v.val_names.is_none());
|
||||
assert!(a.v.num_vals.is_none());
|
||||
|
||||
assert!(a.val_names.is_none());
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
|
|
@ -8,30 +8,29 @@ mod tests {
|
|||
|
||||
fn get_app() -> App<'static, 'static> {
|
||||
App::new("myprog")
|
||||
.arg(Arg::with_name("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help(
|
||||
"Specifies something needed by the subcommands",
|
||||
)
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"))
|
||||
.arg(Arg::with_name("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help(
|
||||
"Specifies something needed by the subcommands",
|
||||
)
|
||||
.multiple(true)
|
||||
.global(true))
|
||||
.subcommand(SubCommand::with_name("outer")
|
||||
.subcommand(SubCommand::with_name("inner")))
|
||||
.arg(
|
||||
Arg::with_name("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.multiple(true)
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("outer").subcommand(SubCommand::with_name("inner")))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1076() {
|
||||
let mut app = get_app();
|
||||
app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
let _ = app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
let _ = app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
let _ = app.get_matches_from_safe_borrow(vec!["myprog"]);
|
||||
}
|
||||
}
|
||||
|
|
158
tests/groups.rs
158
tests/groups.rs
|
@ -13,14 +13,16 @@ USAGE:
|
|||
|
||||
For more information try --help";
|
||||
|
||||
static REQ_GROUP_CONFLICT_USAGE: &'static str = "error: The argument '<base>' cannot be used with '--delete'
|
||||
static REQ_GROUP_CONFLICT_USAGE: &'static str =
|
||||
"error: The argument '<base>' cannot be used with '--delete'
|
||||
|
||||
USAGE:
|
||||
clap-test <base|--delete>
|
||||
|
||||
For more information try --help";
|
||||
|
||||
static REQ_GROUP_CONFLICT_REV: &'static str = "error: The argument '--delete' cannot be used with 'base'
|
||||
static REQ_GROUP_CONFLICT_REV: &'static str =
|
||||
"error: The argument '--delete' cannot be used with 'base'
|
||||
|
||||
USAGE:
|
||||
clap-test <base|--delete>
|
||||
|
@ -30,11 +32,15 @@ For more information try --help";
|
|||
#[test]
|
||||
fn required_group_missing_arg() {
|
||||
let result = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'")
|
||||
.group(ArgGroup::with_name("req")
|
||||
.args(&["flag", "color"])
|
||||
.required(true))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'",
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("req")
|
||||
.args(&["flag", "color"])
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -45,21 +51,26 @@ fn required_group_missing_arg() {
|
|||
#[should_panic]
|
||||
fn non_existing_arg() {
|
||||
let _ = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'")
|
||||
.group(ArgGroup::with_name("req")
|
||||
.args(&["flg", "color"])
|
||||
.required(true))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'",
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("req")
|
||||
.args(&["flg", "color"])
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from_safe(vec![""]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_single_value() {
|
||||
let res = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'")
|
||||
.group(ArgGroup::with_name("grp")
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'",
|
||||
)
|
||||
.group(ArgGroup::with_name("grp").args(&["flag", "color"]))
|
||||
.get_matches_from_safe(vec!["", "-c", "blue"]);
|
||||
assert!(res.is_ok());
|
||||
|
||||
|
@ -71,10 +82,11 @@ fn group_single_value() {
|
|||
#[test]
|
||||
fn group_single_flag() {
|
||||
let res = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'")
|
||||
.group(ArgGroup::with_name("grp")
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'",
|
||||
)
|
||||
.group(ArgGroup::with_name("grp").args(&["flag", "color"]))
|
||||
.get_matches_from_safe(vec!["", "-f"]);
|
||||
assert!(res.is_ok());
|
||||
|
||||
|
@ -86,10 +98,11 @@ fn group_single_flag() {
|
|||
#[test]
|
||||
fn group_empty() {
|
||||
let res = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'")
|
||||
.group(ArgGroup::with_name("grp")
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color [color] 'some option'",
|
||||
)
|
||||
.group(ArgGroup::with_name("grp").args(&["flag", "color"]))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(res.is_ok());
|
||||
|
||||
|
@ -101,11 +114,15 @@ fn group_empty() {
|
|||
#[test]
|
||||
fn group_reqired_flags_empty() {
|
||||
let result = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color 'some option'")
|
||||
.group(ArgGroup::with_name("grp")
|
||||
.required(true)
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color 'some option'",
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("grp")
|
||||
.required(true)
|
||||
.args(&["flag", "color"]),
|
||||
)
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -115,24 +132,27 @@ fn group_reqired_flags_empty() {
|
|||
#[test]
|
||||
fn group_multi_value_single_arg() {
|
||||
let res = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color [color]... 'some option'")
|
||||
.group(ArgGroup::with_name("grp")
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color [color]... 'some option'",
|
||||
)
|
||||
.group(ArgGroup::with_name("grp").args(&["flag", "color"]))
|
||||
.get_matches_from_safe(vec!["", "-c", "blue", "red", "green"]);
|
||||
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind);
|
||||
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("grp"));
|
||||
assert_eq!(&*m.values_of("grp").unwrap().collect::<Vec<_>>(), &["blue", "red", "green"]);
|
||||
assert_eq!(
|
||||
&*m.values_of("grp").unwrap().collect::<Vec<_>>(),
|
||||
&["blue", "red", "green"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_group() {
|
||||
let r = App::new("empty_group")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'"))
|
||||
.group(ArgGroup::with_name("vers")
|
||||
.required(true))
|
||||
.group(ArgGroup::with_name("vers").required(true))
|
||||
.get_matches_from_safe(vec!["empty_prog"]);
|
||||
assert!(r.is_err());
|
||||
let err = r.err().unwrap();
|
||||
|
@ -142,36 +162,59 @@ fn empty_group() {
|
|||
#[test]
|
||||
fn req_group_usage_string() {
|
||||
let app = App::new("req_group")
|
||||
.args_from_usage("[base] 'Base commit'
|
||||
-d, --delete 'Remove the base commit information'")
|
||||
.group(ArgGroup::with_name("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true));
|
||||
.args_from_usage(
|
||||
"[base] 'Base commit'
|
||||
-d, --delete 'Remove the base commit information'",
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "clap-test", REQ_GROUP_USAGE, true));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test",
|
||||
REQ_GROUP_USAGE,
|
||||
true
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn req_group_with_conflict_usage_string() {
|
||||
let app = App::new("req_group")
|
||||
.arg(Arg::from_usage("[base] 'Base commit'").conflicts_with("delete"))
|
||||
.arg(Arg::from_usage("-d, --delete 'Remove the base commit information'"))
|
||||
.group(ArgGroup::with_name("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true));
|
||||
.arg(Arg::from_usage(
|
||||
"-d, --delete 'Remove the base commit information'",
|
||||
))
|
||||
.group(
|
||||
ArgGroup::with_name("base_or_delete")
|
||||
.args(&["base", "delete"])
|
||||
.required(true),
|
||||
);
|
||||
|
||||
assert!(test::compare_output2(app, "clap-test --delete base", REQ_GROUP_CONFLICT_REV, REQ_GROUP_CONFLICT_USAGE, true));
|
||||
assert!(test::compare_output2(
|
||||
app,
|
||||
"clap-test --delete base",
|
||||
REQ_GROUP_CONFLICT_REV,
|
||||
REQ_GROUP_CONFLICT_USAGE,
|
||||
true
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_group_multiple_args() {
|
||||
let result = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'")
|
||||
.group(ArgGroup::with_name("req")
|
||||
.args(&["flag", "color"])
|
||||
.required(true)
|
||||
.multiple(true))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'",
|
||||
)
|
||||
.group(
|
||||
ArgGroup::with_name("req")
|
||||
.args(&["flag", "color"])
|
||||
.required(true)
|
||||
.multiple(true),
|
||||
)
|
||||
.get_matches_from_safe(vec!["group", "-f", "-c"]);
|
||||
assert!(result.is_ok());
|
||||
let m = result.unwrap();
|
||||
|
@ -182,10 +225,11 @@ fn required_group_multiple_args() {
|
|||
#[test]
|
||||
fn group_multiple_args_error() {
|
||||
let result = App::new("group")
|
||||
.args_from_usage("-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'")
|
||||
.group(ArgGroup::with_name("req")
|
||||
.args(&["flag", "color"]))
|
||||
.args_from_usage(
|
||||
"-f, --flag 'some flag'
|
||||
-c, --color 'some other flag'",
|
||||
)
|
||||
.group(ArgGroup::with_name("req").args(&["flag", "color"]))
|
||||
.get_matches_from_safe(vec!["group", "-f", "-c"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.unwrap_err();
|
||||
|
|
663
tests/help.rs
663
tests/help.rs
|
@ -4,7 +4,7 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, AppSettings, SubCommand, ErrorKind, Arg};
|
||||
use clap::{App, AppSettings, Arg, ErrorKind, SubCommand};
|
||||
|
||||
static REQUIRE_DELIM_HELP: &'static str = "test 1.3
|
||||
Kevin K.
|
||||
|
@ -180,7 +180,6 @@ FLAGS:
|
|||
-h, --help Prints help information
|
||||
-V, --version Prints version information";
|
||||
|
||||
|
||||
static MULTI_SC_HELP: &'static str = "ctest-subcmd-multi 0.1
|
||||
Kevin K. <kbknapp@gmail.com>
|
||||
tests subcommands
|
||||
|
@ -526,8 +525,7 @@ fn setup() -> App<'static, 'static> {
|
|||
|
||||
#[test]
|
||||
fn help_short() {
|
||||
let m = setup()
|
||||
.get_matches_from_safe(vec!["myprog", "-h"]);
|
||||
let m = setup().get_matches_from_safe(vec!["myprog", "-h"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
|
||||
|
@ -535,8 +533,7 @@ fn help_short() {
|
|||
|
||||
#[test]
|
||||
fn help_long() {
|
||||
let m = setup()
|
||||
.get_matches_from_safe(vec!["myprog", "--help"]);
|
||||
let m = setup().get_matches_from_safe(vec!["myprog", "--help"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
|
||||
|
@ -544,8 +541,7 @@ fn help_long() {
|
|||
|
||||
#[test]
|
||||
fn help_no_subcommand() {
|
||||
let m = setup()
|
||||
.get_matches_from_safe(vec!["myprog", "help"]);
|
||||
let m = setup().get_matches_from_safe(vec!["myprog", "help"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
|
||||
|
@ -554,9 +550,11 @@ fn help_no_subcommand() {
|
|||
#[test]
|
||||
fn help_subcommand() {
|
||||
let m = setup()
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("tests things")
|
||||
.arg_from_usage("-v --verbose 'with verbosity'"))
|
||||
.subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("tests things")
|
||||
.arg_from_usage("-v --verbose 'with verbosity'"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["myprog", "help"]);
|
||||
|
||||
assert!(m.is_err());
|
||||
|
@ -570,7 +568,12 @@ fn req_last_arg_usage() {
|
|||
(@arg FIRST: ... * "First")
|
||||
(@arg SECOND: ... * +last "Second")
|
||||
);
|
||||
assert!(test::compare_output(app, "example --help", LAST_ARG_REQ_MULT, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"example --help",
|
||||
LAST_ARG_REQ_MULT,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -578,38 +581,48 @@ fn args_with_last_usage() {
|
|||
let app = App::new("flamegraph")
|
||||
.version("0.1")
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(Arg::with_name("verbose")
|
||||
.help("Prints out more stuff.")
|
||||
.short("v")
|
||||
.long("verbose")
|
||||
.multiple(true)
|
||||
.arg(
|
||||
Arg::with_name("verbose")
|
||||
.help("Prints out more stuff.")
|
||||
.short("v")
|
||||
.long("verbose")
|
||||
.multiple(true),
|
||||
)
|
||||
.arg(Arg::with_name("timeout")
|
||||
.help("Timeout in seconds.")
|
||||
.short("t")
|
||||
.long("timeout")
|
||||
.value_name("SECONDS")
|
||||
.takes_value(true)
|
||||
.arg(
|
||||
Arg::with_name("timeout")
|
||||
.help("Timeout in seconds.")
|
||||
.short("t")
|
||||
.long("timeout")
|
||||
.value_name("SECONDS")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name("frequency")
|
||||
.help("The sampling frequency.")
|
||||
.short("f")
|
||||
.long("frequency")
|
||||
.value_name("HERTZ")
|
||||
.takes_value(true)
|
||||
.arg(
|
||||
Arg::with_name("frequency")
|
||||
.help("The sampling frequency.")
|
||||
.short("f")
|
||||
.long("frequency")
|
||||
.value_name("HERTZ")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name("binary path")
|
||||
.help("The path of the binary to be profiled. for a binary.")
|
||||
.takes_value(true)
|
||||
.value_name("BINFILE")
|
||||
.arg(
|
||||
Arg::with_name("binary path")
|
||||
.help("The path of the binary to be profiled. for a binary.")
|
||||
.takes_value(true)
|
||||
.value_name("BINFILE"),
|
||||
)
|
||||
.arg(Arg::with_name("pass through args")
|
||||
.help("Any arguments you wish to pass to the being profiled.")
|
||||
.value_name("ARGS")
|
||||
.last(true)
|
||||
.multiple(true)
|
||||
.arg(
|
||||
Arg::with_name("pass through args")
|
||||
.help("Any arguments you wish to pass to the being profiled.")
|
||||
.value_name("ARGS")
|
||||
.last(true)
|
||||
.multiple(true),
|
||||
);
|
||||
assert!(test::compare_output(app, "flamegraph --help", LAST_ARG_USAGE, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"flamegraph --help",
|
||||
LAST_ARG_USAGE,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -638,7 +651,12 @@ fn subcommand_help_rev() {
|
|||
|
||||
#[test]
|
||||
fn complex_help_output() {
|
||||
assert!(test::compare_output(test::complex_app(), "clap-test --help", HELP, false));
|
||||
assert!(test::compare_output(
|
||||
test::complex_app(),
|
||||
"clap-test --help",
|
||||
HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -648,83 +666,123 @@ fn after_and_before_help_output() {
|
|||
.about("tests clap library")
|
||||
.before_help("some text that comes before the help")
|
||||
.after_help("some text that comes after the help");
|
||||
assert!(test::compare_output(app, "clap-test --help", AFTER_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
AFTER_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_level_sc_help() {
|
||||
let app = App::new("ctest")
|
||||
.subcommand(SubCommand::with_name("subcmd").subcommand(SubCommand::with_name("multi")
|
||||
.about("tests subcommands")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.version("0.1")
|
||||
.args_from_usage("
|
||||
-f, --flag 'tests flags'
|
||||
-o, --option [scoption]... 'tests options'
|
||||
")));
|
||||
assert!(test::compare_output(app, "ctest help subcmd multi", MULTI_SC_HELP, false));
|
||||
let app = App::new("ctest").subcommand(
|
||||
SubCommand::with_name("subcmd").subcommand(
|
||||
SubCommand::with_name("multi")
|
||||
.about("tests subcommands")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.version("0.1")
|
||||
.args_from_usage(
|
||||
"-f, --flag 'tests flags'
|
||||
-o, --option [scoption]... 'tests options'",
|
||||
),
|
||||
),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest help subcmd multi",
|
||||
MULTI_SC_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_wrap_help() {
|
||||
let app = App::new("ctest")
|
||||
.set_term_width(0)
|
||||
.help(MULTI_SC_HELP);
|
||||
assert!(test::compare_output(app, "ctest --help", MULTI_SC_HELP, false));
|
||||
let app = App::new("ctest").set_term_width(0).help(MULTI_SC_HELP);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
MULTI_SC_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_wrap_default_help() {
|
||||
let app = App::new("ctest").version("1.0").set_term_width(0);
|
||||
assert!(test::compare_output(app, "ctest --help", DEFAULT_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
DEFAULT_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn complex_subcommand_help_output() {
|
||||
let a = test::complex_app();
|
||||
assert!(test::compare_output(a, "clap-test subcmd --help", SC_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
a,
|
||||
"clap-test subcmd --help",
|
||||
SC_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn issue_626_unicode_cutoff() {
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.set_term_width(70)
|
||||
.arg(Arg::with_name("cafe")
|
||||
let app = App::new("ctest").version("0.1").set_term_width(70).arg(
|
||||
Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.help("A coffeehouse, coffee shop, or café is an establishment \
|
||||
which primarily serves hot coffee, related coffee beverages \
|
||||
(e.g., café latte, cappuccino, espresso), tea, and other hot \
|
||||
beverages. Some coffeehouses also serve cold beverages such as \
|
||||
iced coffee and iced tea. Many cafés also serve some type of \
|
||||
food, such as light snacks, muffins, or pastries.")
|
||||
.takes_value(true));
|
||||
assert!(test::compare_output(app, "ctest --help", ISSUE_626_CUTOFF, false));
|
||||
.help(
|
||||
"A coffeehouse, coffee shop, or café is an establishment \
|
||||
which primarily serves hot coffee, related coffee beverages \
|
||||
(e.g., café latte, cappuccino, espresso), tea, and other hot \
|
||||
beverages. Some coffeehouses also serve cold beverages such as \
|
||||
iced coffee and iced tea. Many cafés also serve some type of \
|
||||
food, such as light snacks, muffins, or pastries.",
|
||||
)
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
ISSUE_626_CUTOFF,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hide_possible_vals() {
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_possible_values(true)
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true));
|
||||
assert!(test::compare_output(app, "ctest --help", HIDE_POS_VALS, false));
|
||||
.arg(
|
||||
Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_possible_values(true)
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
HIDE_POS_VALS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -740,7 +798,12 @@ fn issue_626_panic() {
|
|||
d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
|
||||
Le café est souvent une contribution majeure aux exportations des régions productrices.")
|
||||
.takes_value(true));
|
||||
assert!(test::compare_output(app, "ctest --help", ISSUE_626_PANIC, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
ISSUE_626_PANIC,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -764,29 +827,44 @@ fn issue_626_variable_panic() {
|
|||
#[test]
|
||||
fn final_word_wrapping() {
|
||||
let app = App::new("ctest").version("0.1").set_term_width(24);
|
||||
assert!(test::compare_output(app, "ctest --help", FINAL_WORD_WRAPPING, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
FINAL_WORD_WRAPPING,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wrapping_newline_chars() {
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.set_term_width(60)
|
||||
.arg(Arg::with_name("mode")
|
||||
.help("x, max, maximum 20 characters, contains symbols.{n}\
|
||||
l, long Copy-friendly, 14 characters, contains symbols.{n}\
|
||||
m, med, medium Copy-friendly, 8 characters, contains symbols.{n}"));
|
||||
assert!(test::compare_output(app, "ctest --help", WRAPPING_NEWLINE_CHARS, false));
|
||||
let app = App::new("ctest").version("0.1").set_term_width(60).arg(
|
||||
Arg::with_name("mode").help(
|
||||
"x, max, maximum 20 characters, contains symbols.{n}\
|
||||
l, long Copy-friendly, 14 characters, contains symbols.{n}\
|
||||
m, med, medium Copy-friendly, 8 characters, contains symbols.{n}",
|
||||
),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
WRAPPING_NEWLINE_CHARS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn old_newline_chars() {
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("mode")
|
||||
let app = App::new("ctest").version("0.1").arg(
|
||||
Arg::with_name("mode")
|
||||
.short("m")
|
||||
.help("Some help with some wrapping{n}(Defaults to something)"));
|
||||
assert!(test::compare_output(app, "ctest --help", OLD_NEWLINE_CHARS, false));
|
||||
.help("Some help with some wrapping{n}(Defaults to something)"),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
OLD_NEWLINE_CHARS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -834,25 +912,29 @@ fn issue_702_multiple_values() {
|
|||
.author("foo")
|
||||
.about("bar")
|
||||
.arg(Arg::with_name("arg1").help("some option"))
|
||||
.arg(Arg::with_name("arg2")
|
||||
.multiple(true)
|
||||
.help("some option"))
|
||||
.arg(Arg::with_name("some")
|
||||
.help("some option")
|
||||
.short("s")
|
||||
.long("some")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("other")
|
||||
.help("some other option")
|
||||
.short("o")
|
||||
.long("other")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("label")
|
||||
.help("a label")
|
||||
.short("l")
|
||||
.long("label")
|
||||
.multiple(true)
|
||||
.takes_value(true));
|
||||
.arg(Arg::with_name("arg2").multiple(true).help("some option"))
|
||||
.arg(
|
||||
Arg::with_name("some")
|
||||
.help("some option")
|
||||
.short("s")
|
||||
.long("some")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("other")
|
||||
.help("some other option")
|
||||
.short("o")
|
||||
.long("other")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("label")
|
||||
.help("a label")
|
||||
.short("l")
|
||||
.long("label")
|
||||
.multiple(true)
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(app, "myapp --help", ISSUE_702, false));
|
||||
}
|
||||
|
||||
|
@ -862,7 +944,9 @@ fn long_about() {
|
|||
.version("1.0")
|
||||
.author("foo")
|
||||
.about("bar")
|
||||
.long_about("something really really long, with\nmultiple lines of text\nthat should be displayed")
|
||||
.long_about(
|
||||
"something really really long, with\nmultiple lines of text\nthat should be displayed",
|
||||
)
|
||||
.arg(Arg::with_name("arg1").help("some option"));
|
||||
assert!(test::compare_output(app, "myapp --help", LONG_ABOUT, false));
|
||||
}
|
||||
|
@ -871,29 +955,33 @@ fn long_about() {
|
|||
fn issue_760() {
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("option")
|
||||
.help("tests options")
|
||||
.short("o")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.number_of_values(1))
|
||||
.arg(Arg::with_name("opt")
|
||||
.help("tests options")
|
||||
.short("O")
|
||||
.long("opt")
|
||||
.takes_value(true));
|
||||
.arg(
|
||||
Arg::with_name("option")
|
||||
.help("tests options")
|
||||
.short("o")
|
||||
.long("option")
|
||||
.takes_value(true)
|
||||
.multiple(true)
|
||||
.number_of_values(1),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
.help("tests options")
|
||||
.short("O")
|
||||
.long("opt")
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(app, "ctest --help", ISSUE_760, false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ripgrep_usage() {
|
||||
let app = App::new("ripgrep")
|
||||
.version("0.5")
|
||||
.usage("rg [OPTIONS] <pattern> [<path> ...]
|
||||
let app = App::new("ripgrep").version("0.5").usage(
|
||||
"rg [OPTIONS] <pattern> [<path> ...]
|
||||
rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
|
||||
rg [OPTIONS] --files [<path> ...]
|
||||
rg [OPTIONS] --type-list");
|
||||
rg [OPTIONS] --type-list",
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "rg --help", RIPGREP_USAGE, false));
|
||||
}
|
||||
|
@ -902,18 +990,22 @@ fn ripgrep_usage() {
|
|||
fn ripgrep_usage_using_templates() {
|
||||
let app = App::new("ripgrep")
|
||||
.version("0.5")
|
||||
.usage("
|
||||
.usage(
|
||||
"
|
||||
rg [OPTIONS] <pattern> [<path> ...]
|
||||
rg [OPTIONS] [-e PATTERN | -f FILE ]... [<path> ...]
|
||||
rg [OPTIONS] --files [<path> ...]
|
||||
rg [OPTIONS] --type-list")
|
||||
.template("\
|
||||
rg [OPTIONS] --type-list",
|
||||
)
|
||||
.template(
|
||||
"\
|
||||
{bin} {version}
|
||||
|
||||
USAGE:{usage}
|
||||
|
||||
FLAGS:
|
||||
{flags}");
|
||||
{flags}",
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "rg --help", RIPGREP_USAGE, false));
|
||||
}
|
||||
|
@ -926,15 +1018,22 @@ fn sc_negates_reqs() {
|
|||
.arg_from_usage("-o, --opt <FILE> 'tests options'")
|
||||
.arg(Arg::with_name("PATH").help("help"))
|
||||
.subcommand(SubCommand::with_name("test"));
|
||||
assert!(test::compare_output(app, "prog --help", SC_NEGATES_REQS, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"prog --help",
|
||||
SC_NEGATES_REQS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hidden_args() {
|
||||
let app = App::new("prog")
|
||||
.version("1.0")
|
||||
.args_from_usage("-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'")
|
||||
.args_from_usage(
|
||||
"-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'",
|
||||
)
|
||||
.arg(Arg::with_name("pos").hidden(true));
|
||||
assert!(test::compare_output(app, "prog --help", HIDDEN_ARGS, false));
|
||||
}
|
||||
|
@ -944,22 +1043,36 @@ fn args_negate_sc() {
|
|||
let app = App::new("prog")
|
||||
.version("1.0")
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.args_from_usage("-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'")
|
||||
.args_from_usage(
|
||||
"-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'",
|
||||
)
|
||||
.arg(Arg::with_name("PATH").help("help"))
|
||||
.subcommand(SubCommand::with_name("test"));
|
||||
assert!(test::compare_output(app, "prog --help", ARGS_NEGATE_SC, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"prog --help",
|
||||
ARGS_NEGATE_SC,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1046_hidden_scs() {
|
||||
let app = App::new("prog")
|
||||
.version("1.0")
|
||||
.args_from_usage("-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'")
|
||||
.args_from_usage(
|
||||
"-f, --flag 'testing flags'
|
||||
-o, --opt [FILE] 'tests options'",
|
||||
)
|
||||
.arg(Arg::with_name("PATH").help("some"))
|
||||
.subcommand(SubCommand::with_name("test").setting(AppSettings::Hidden));
|
||||
assert!(test::compare_output(app, "prog --help", ISSUE_1046_HIDDEN_SCS, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"prog --help",
|
||||
ISSUE_1046_HIDDEN_SCS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -982,74 +1095,118 @@ fn customize_version_and_help() {
|
|||
.help_message("Print help information")
|
||||
.version_short("v")
|
||||
.version_message("Print version information");
|
||||
assert!(test::compare_output(app, "customize --help", CUSTOM_VERSION_AND_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"customize --help",
|
||||
CUSTOM_VERSION_AND_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_arg_mult_usage() {
|
||||
let app = App::new("last")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(Arg::with_name("ARGS").multiple(true).last(true).help("some"));
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(
|
||||
Arg::with_name("ARGS")
|
||||
.multiple(true)
|
||||
.last(true)
|
||||
.help("some"),
|
||||
);
|
||||
assert!(test::compare_output(app, "last --help", LAST_ARG, false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_arg_mult_usage_req() {
|
||||
let app = App::new("last")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(Arg::with_name("ARGS").multiple(true).last(true).required(true).help("some"));
|
||||
assert!(test::compare_output(app, "last --help", LAST_ARG_REQ, false));
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(
|
||||
Arg::with_name("ARGS")
|
||||
.multiple(true)
|
||||
.last(true)
|
||||
.required(true)
|
||||
.help("some"),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"last --help",
|
||||
LAST_ARG_REQ,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_arg_mult_usage_req_with_sc() {
|
||||
let app = App::new("last")
|
||||
.version("0.1")
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(Arg::with_name("ARGS").multiple(true).last(true).required(true).help("some"))
|
||||
.subcommand(SubCommand::with_name("test").about("some"));
|
||||
assert!(test::compare_output(app, "last --help", LAST_ARG_REQ_SC, false));
|
||||
.version("0.1")
|
||||
.setting(AppSettings::SubcommandsNegateReqs)
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(
|
||||
Arg::with_name("ARGS")
|
||||
.multiple(true)
|
||||
.last(true)
|
||||
.required(true)
|
||||
.help("some"),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("test").about("some"));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"last --help",
|
||||
LAST_ARG_REQ_SC,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn last_arg_mult_usage_with_sc() {
|
||||
let app = App::new("last")
|
||||
.version("0.1")
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(Arg::with_name("ARGS").multiple(true).last(true).help("some"))
|
||||
.subcommand(SubCommand::with_name("test").about("some"));
|
||||
.version("0.1")
|
||||
.setting(AppSettings::ArgsNegateSubcommands)
|
||||
.arg(Arg::with_name("TARGET").required(true).help("some"))
|
||||
.arg(Arg::with_name("CORPUS").help("some"))
|
||||
.arg(
|
||||
Arg::with_name("ARGS")
|
||||
.multiple(true)
|
||||
.last(true)
|
||||
.help("some"),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("test").about("some"));
|
||||
assert!(test::compare_output(app, "last --help", LAST_ARG_SC, false));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn hidden_default_val() {
|
||||
let app1 = App::new("default")
|
||||
.version("0.1")
|
||||
.set_term_width(120)
|
||||
.arg(Arg::with_name("argument")
|
||||
.help("Pass an argument to the program. [default: default-argument]")
|
||||
.long("arg")
|
||||
.default_value("default-argument")
|
||||
.hide_default_value(true));
|
||||
assert!(test::compare_output(app1, "default --help", HIDE_DEFAULT_VAL, false));
|
||||
let app1 = App::new("default").version("0.1").set_term_width(120).arg(
|
||||
Arg::with_name("argument")
|
||||
.help("Pass an argument to the program. [default: default-argument]")
|
||||
.long("arg")
|
||||
.default_value("default-argument")
|
||||
.hide_default_value(true),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app1,
|
||||
"default --help",
|
||||
HIDE_DEFAULT_VAL,
|
||||
false
|
||||
));
|
||||
|
||||
let app2 = App::new("default")
|
||||
.version("0.1")
|
||||
.set_term_width(120)
|
||||
.arg(Arg::with_name("argument")
|
||||
.help("Pass an argument to the program.")
|
||||
.long("arg")
|
||||
.default_value("default-argument"));
|
||||
assert!(test::compare_output(app2, "default --help", HIDE_DEFAULT_VAL, false));
|
||||
let app2 = App::new("default").version("0.1").set_term_width(120).arg(
|
||||
Arg::with_name("argument")
|
||||
.help("Pass an argument to the program.")
|
||||
.long("arg")
|
||||
.default_value("default-argument"),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app2,
|
||||
"default --help",
|
||||
HIDE_DEFAULT_VAL,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
fn issue_1112_setup() -> App<'static, 'static> {
|
||||
|
@ -1058,14 +1215,12 @@ fn issue_1112_setup() -> App<'static, 'static> {
|
|||
.about("tests stuff")
|
||||
.version("1.3")
|
||||
.arg(Arg::from_usage("-h, --help 'some help'"))
|
||||
.subcommand(SubCommand::with_name("foo")
|
||||
.arg(Arg::from_usage("-h, --help 'some help'")))
|
||||
.subcommand(SubCommand::with_name("foo").arg(Arg::from_usage("-h, --help 'some help'")))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1112_override_help_long() {
|
||||
let m = issue_1112_setup()
|
||||
.get_matches_from_safe(vec!["test", "--help"]);
|
||||
let m = issue_1112_setup().get_matches_from_safe(vec!["test", "--help"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
assert!(m.unwrap().is_present("help"));
|
||||
|
@ -1073,8 +1228,7 @@ fn issue_1112_override_help_long() {
|
|||
|
||||
#[test]
|
||||
fn issue_1112_override_help_short() {
|
||||
let m = issue_1112_setup()
|
||||
.get_matches_from_safe(vec!["test", "-h"]);
|
||||
let m = issue_1112_setup().get_matches_from_safe(vec!["test", "-h"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
assert!(m.unwrap().is_present("help"));
|
||||
|
@ -1082,20 +1236,28 @@ fn issue_1112_override_help_short() {
|
|||
|
||||
#[test]
|
||||
fn issue_1112_override_help_subcmd_long() {
|
||||
let m = issue_1112_setup()
|
||||
.get_matches_from_safe(vec!["test", "foo", "--help"]);
|
||||
let m = issue_1112_setup().get_matches_from_safe(vec!["test", "foo", "--help"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
assert!(m.unwrap().subcommand_matches("foo").unwrap().is_present("help"));
|
||||
assert!(
|
||||
m.unwrap()
|
||||
.subcommand_matches("foo")
|
||||
.unwrap()
|
||||
.is_present("help")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_1112_override_help_subcmd_short() {
|
||||
let m = issue_1112_setup()
|
||||
.get_matches_from_safe(vec!["test", "foo", "-h"]);
|
||||
let m = issue_1112_setup().get_matches_from_safe(vec!["test", "foo", "-h"]);
|
||||
|
||||
assert!(m.is_ok());
|
||||
assert!(m.unwrap().subcommand_matches("foo").unwrap().is_present("help"));
|
||||
assert!(
|
||||
m.unwrap()
|
||||
.subcommand_matches("foo")
|
||||
.unwrap()
|
||||
.is_present("help")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1104,9 +1266,18 @@ fn issue_1052_require_delim_help() {
|
|||
.author("Kevin K.")
|
||||
.about("tests stuff")
|
||||
.version("1.3")
|
||||
.arg(Arg::from_usage("-f, --fake <some> <val> 'some help'").require_delimiter(true).value_delimiter(":"));
|
||||
.arg(
|
||||
Arg::from_usage("-f, --fake <some> <val> 'some help'")
|
||||
.require_delimiter(true)
|
||||
.value_delimiter(":"),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app, "test --help", REQUIRE_DELIM_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --help",
|
||||
REQUIRE_DELIM_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1116,22 +1287,31 @@ fn hide_env_vals() {
|
|||
env::set_var("ENVVAR", "MYVAL");
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_env_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true));
|
||||
assert!(test::compare_output(app, "ctest --help", HIDE_ENV_VALS, false));
|
||||
.arg(
|
||||
Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_env_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
HIDE_ENV_VALS,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1141,20 +1321,29 @@ fn show_env_vals() {
|
|||
env::set_var("ENVVAR", "MYVAL");
|
||||
let app = App::new("ctest")
|
||||
.version("0.1")
|
||||
.arg(Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_possible_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true));
|
||||
assert!(test::compare_output(app, "ctest --help", SHOW_ENV_VALS, false));
|
||||
.arg(
|
||||
Arg::with_name("pos")
|
||||
.short("p")
|
||||
.long("pos")
|
||||
.value_name("VAL")
|
||||
.possible_values(&["fast", "slow"])
|
||||
.help("Some vals")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("cafe")
|
||||
.short("c")
|
||||
.long("cafe")
|
||||
.value_name("FILE")
|
||||
.hide_possible_values(true)
|
||||
.env("ENVVAR")
|
||||
.help("A coffeehouse, coffee shop, or café.")
|
||||
.takes_value(true),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"ctest --help",
|
||||
SHOW_ENV_VALS,
|
||||
false
|
||||
));
|
||||
}
|
|
@ -26,9 +26,11 @@ fn hidden_args() {
|
|||
.author("Kevin K.")
|
||||
.about("tests stuff")
|
||||
.version("1.4")
|
||||
.args(&[Arg::from_usage("-f, --flag 'some flag'").hidden(true),
|
||||
Arg::from_usage("-F, --flag2 'some other flag'"),
|
||||
Arg::from_usage("--option [opt] 'some option'"),
|
||||
Arg::with_name("DUMMY").required(false).hidden(true)]);
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'").hidden(true),
|
||||
Arg::from_usage("-F, --flag2 'some other flag'"),
|
||||
Arg::from_usage("--option [opt] 'some option'"),
|
||||
Arg::with_name("DUMMY").required(false).hidden(true),
|
||||
]);
|
||||
assert!(test::compare_output(app, "test --help", HIDDEN_ARGS, false));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ fn basic() {
|
|||
|
||||
#[test]
|
||||
fn quoted_app_name() {
|
||||
let app = clap_app!(("app name with spaces-and-hyphens") =>
|
||||
let mut app = clap_app!(("app name with spaces-and-hyphens") =>
|
||||
(version: "0.1")
|
||||
(about: "tests clap library")
|
||||
(author: "Kevin K. <kbknapp@gmail.com>")
|
||||
|
@ -66,10 +66,11 @@ fn quoted_app_name() {
|
|||
(@arg scpositional: index(1) "tests positionals"))
|
||||
);
|
||||
|
||||
assert_eq!(app.p.meta.name, "app name with spaces-and-hyphens");
|
||||
assert_eq!(app.name, "app name with spaces-and-hyphens");
|
||||
|
||||
let mut help_text = vec![];
|
||||
app.write_help(&mut help_text).expect("Could not write help text.");
|
||||
app.write_help(&mut help_text)
|
||||
.expect("Could not write help text.");
|
||||
let help_text = String::from_utf8(help_text).expect("Help text is not valid utf-8");
|
||||
assert!(help_text.starts_with("app name with spaces-and-hyphens 0.1\n"));
|
||||
}
|
||||
|
@ -106,8 +107,9 @@ fn quoted_arg_long_name() {
|
|||
(@arg scpositional: index(1) "tests positionals"))
|
||||
);
|
||||
|
||||
let matches = app.get_matches_from_safe(vec!["bin_name", "value1", "value2", "--long-option-2"])
|
||||
.expect("Expected to successfully match the given args.");
|
||||
let matches =
|
||||
app.get_matches_from_safe(vec!["bin_name", "value1", "value2", "--long-option-2"])
|
||||
.expect("Expected to successfully match the given args.");
|
||||
assert!(matches.is_present("option2"));
|
||||
}
|
||||
|
||||
|
@ -143,8 +145,9 @@ fn quoted_arg_name() {
|
|||
(@arg scpositional: index(1) "tests positionals"))
|
||||
);
|
||||
|
||||
let matches = app.get_matches_from_safe(vec!["bin_name", "value1", "value2", "--long-option-2"])
|
||||
.expect("Expected to successfully match the given args.");
|
||||
let matches =
|
||||
app.get_matches_from_safe(vec!["bin_name", "value1", "value2", "--long-option-2"])
|
||||
.expect("Expected to successfully match the given args.");
|
||||
assert!(matches.is_present("option2"));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,9 @@ use clap::{App, Arg};
|
|||
#[test]
|
||||
fn multiple_occurrences_of_flags_long() {
|
||||
let m = App::new("mo_flags_long")
|
||||
.arg(Arg::from_usage("--multflag 'allowed multiple flag'")
|
||||
.multiple(true))
|
||||
.arg(Arg::from_usage("--flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec![
|
||||
"",
|
||||
"--multflag",
|
||||
"--flag",
|
||||
"--multflag"
|
||||
]);
|
||||
.arg(Arg::from_usage("--multflag 'allowed multiple flag'").multiple(true))
|
||||
.arg(Arg::from_usage("--flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]);
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 2);
|
||||
assert!(m.is_present("flag"));
|
||||
|
@ -23,15 +17,9 @@ fn multiple_occurrences_of_flags_long() {
|
|||
#[test]
|
||||
fn multiple_occurrences_of_flags_short() {
|
||||
let m = App::new("mo_flags_short")
|
||||
.arg(Arg::from_usage("-m --multflag 'allowed multiple flag'")
|
||||
.multiple(true))
|
||||
.arg(Arg::from_usage("-f --flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec![
|
||||
"",
|
||||
"-m",
|
||||
"-f",
|
||||
"-m"
|
||||
]);
|
||||
.arg(Arg::from_usage("-m --multflag 'allowed multiple flag'").multiple(true))
|
||||
.arg(Arg::from_usage("-f --flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec!["", "-m", "-f", "-m"]);
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 2);
|
||||
assert!(m.is_present("flag"));
|
||||
|
@ -41,20 +29,18 @@ fn multiple_occurrences_of_flags_short() {
|
|||
#[test]
|
||||
fn multiple_occurrences_of_flags_mixed() {
|
||||
let m = App::new("mo_flags_mixed")
|
||||
.arg(Arg::from_usage("-m, --multflag1 'allowed multiple flag'")
|
||||
.multiple(true))
|
||||
.arg(Arg::from_usage("-n, --multflag2 'another allowed multiple flag'")
|
||||
.multiple(true))
|
||||
.arg(Arg::from_usage("-f, --flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec![
|
||||
"",
|
||||
"-m",
|
||||
"-f",
|
||||
"-n",
|
||||
"--multflag1",
|
||||
"-m",
|
||||
"--multflag2"
|
||||
]);
|
||||
.arg(Arg::from_usage("-m, --multflag1 'allowed multiple flag'").multiple(true))
|
||||
.arg(Arg::from_usage("-n, --multflag2 'another allowed multiple flag'").multiple(true))
|
||||
.arg(Arg::from_usage("-f, --flag 'disallowed multiple flag'"))
|
||||
.get_matches_from(vec![
|
||||
"",
|
||||
"-m",
|
||||
"-f",
|
||||
"-n",
|
||||
"--multflag1",
|
||||
"-m",
|
||||
"--multflag2",
|
||||
]);
|
||||
assert!(m.is_present("multflag1"));
|
||||
assert_eq!(m.occurrences_of("multflag1"), 3);
|
||||
assert!(m.is_present("multflag2"));
|
||||
|
@ -65,11 +51,13 @@ fn multiple_occurrences_of_flags_mixed() {
|
|||
|
||||
#[test]
|
||||
fn multiple_occurrences_of_flags_large_quantity() {
|
||||
let args : Vec<&str> = vec![""].into_iter().chain(vec!["-m"; 1024].into_iter()).collect();
|
||||
let args: Vec<&str> = vec![""]
|
||||
.into_iter()
|
||||
.chain(vec!["-m"; 1024].into_iter())
|
||||
.collect();
|
||||
let m = App::new("mo_flags_larg_qty")
|
||||
.arg(Arg::from_usage("-m --multflag 'allowed multiple flag'")
|
||||
.multiple(true))
|
||||
.get_matches_from(args);
|
||||
.arg(Arg::from_usage("-m --multflag 'allowed multiple flag'").multiple(true))
|
||||
.get_matches_from(args);
|
||||
assert!(m.is_present("multflag"));
|
||||
assert_eq!(m.occurrences_of("multflag"), 1024);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
218
tests/opts.rs
218
tests/opts.rs
|
@ -3,10 +3,11 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, ArgMatches, Arg, ErrorKind};
|
||||
use clap::{App, Arg, ArgMatches, ErrorKind};
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM: &'static str = "error: Found argument '--optio' which wasn't expected, or isn't valid in this context
|
||||
static DYM: &'static str =
|
||||
"error: Found argument '--optio' which wasn't expected, or isn't valid in this context
|
||||
\tDid you mean --option?
|
||||
|
||||
USAGE:
|
||||
|
@ -17,13 +18,13 @@ For more information try --help";
|
|||
#[test]
|
||||
fn require_equals_fail() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config", "file.conf"
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["prog", "--config", "file.conf"]);
|
||||
assert!(res.is_err());
|
||||
assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
|
||||
}
|
||||
|
@ -31,15 +32,15 @@ fn require_equals_fail() {
|
|||
#[test]
|
||||
fn require_equals_min_values_zero() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.min_values(0)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.min_values(0)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("cmd"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config", "cmd"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "--config", "cmd"]);
|
||||
assert!(res.is_ok());
|
||||
let m = res.unwrap();
|
||||
assert!(m.is_present("cfg"));
|
||||
|
@ -49,13 +50,13 @@ fn require_equals_min_values_zero() {
|
|||
#[test]
|
||||
fn double_hyphen_as_value() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.long("config"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config", "--"
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.long("config"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["prog", "--config", "--"]);
|
||||
assert!(res.is_ok(), "{:?}", res);
|
||||
assert_eq!(res.unwrap().value_of("cfg"), Some("--"));
|
||||
}
|
||||
|
@ -63,14 +64,14 @@ fn double_hyphen_as_value() {
|
|||
#[test]
|
||||
fn require_equals_no_empty_values_fail() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("some"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config=", "file.conf"
|
||||
]);
|
||||
.get_matches_from_safe(vec!["prog", "--config=", "file.conf"]);
|
||||
assert!(res.is_err());
|
||||
assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
|
||||
}
|
||||
|
@ -78,27 +79,27 @@ fn require_equals_no_empty_values_fail() {
|
|||
#[test]
|
||||
fn require_equals_empty_vals_pass() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.empty_values(true)
|
||||
.long("config"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config="
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.empty_values(true)
|
||||
.long("config"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["prog", "--config="]);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_equals_pass() {
|
||||
let res = App::new("prog")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.get_matches_from_safe(vec![
|
||||
"prog", "--config=file.conf"
|
||||
]);
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.require_equals(true)
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["prog", "--config=file.conf"]);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
|
@ -116,8 +117,10 @@ fn stdin_char() {
|
|||
#[test]
|
||||
fn opts_using_short() {
|
||||
let r = App::new("opts")
|
||||
.args(&[Arg::from_usage("-f [flag] 'some flag'"),
|
||||
Arg::from_usage("-c [color] 'some other flag'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f [flag] 'some flag'"),
|
||||
Arg::from_usage("-c [color] 'some other flag'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "some", "-c", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -131,49 +134,36 @@ fn opts_using_short() {
|
|||
fn lots_o_vals() {
|
||||
let r = App::new("opts")
|
||||
.arg(Arg::from_usage("-o [opt]... 'some opt'"))
|
||||
.get_matches_from_safe(vec!["", "-o", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some"]);
|
||||
.get_matches_from_safe(vec![
|
||||
"", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some",
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("o"));
|
||||
|
@ -183,8 +173,10 @@ fn lots_o_vals() {
|
|||
#[test]
|
||||
fn opts_using_long_space() {
|
||||
let r = App::new("opts")
|
||||
.args(&[Arg::from_usage("--flag [flag] 'some flag'"),
|
||||
Arg::from_usage("--color [color] 'some other flag'")])
|
||||
.args(&[
|
||||
Arg::from_usage("--flag [flag] 'some flag'"),
|
||||
Arg::from_usage("--color [color] 'some other flag'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--flag", "some", "--color", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -197,8 +189,10 @@ fn opts_using_long_space() {
|
|||
#[test]
|
||||
fn opts_using_long_equals() {
|
||||
let r = App::new("opts")
|
||||
.args(&[Arg::from_usage("--flag [flag] 'some flag'"),
|
||||
Arg::from_usage("--color [color] 'some other flag'")])
|
||||
.args(&[
|
||||
Arg::from_usage("--flag [flag] 'some flag'"),
|
||||
Arg::from_usage("--color [color] 'some other flag'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--flag=some", "--color=other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -211,8 +205,10 @@ fn opts_using_long_equals() {
|
|||
#[test]
|
||||
fn opts_using_mixed() {
|
||||
let r = App::new("opts")
|
||||
.args(&[Arg::from_usage("-f, --flag [flag] 'some flag'"),
|
||||
Arg::from_usage("-c, --color [color] 'some other flag'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag [flag] 'some flag'"),
|
||||
Arg::from_usage("-c, --color [color] 'some other flag'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "some", "--color", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -225,8 +221,10 @@ fn opts_using_mixed() {
|
|||
#[test]
|
||||
fn opts_using_mixed2() {
|
||||
let r = App::new("opts")
|
||||
.args(&[Arg::from_usage("-f, --flag [flag] 'some flag'"),
|
||||
Arg::from_usage("-c, --color [color] 'some other flag'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag [flag] 'some flag'"),
|
||||
Arg::from_usage("-c, --color [color] 'some other flag'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--flag=some", "-c", "other"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -350,7 +348,11 @@ fn leading_hyphen_with_flag_before() {
|
|||
#[test]
|
||||
fn leading_hyphen_with_only_pos_follows() {
|
||||
let r = App::new("mvae")
|
||||
.arg(Arg::from_usage("-o [opt]... 'some opt'").number_of_values(1).allow_hyphen_values(true))
|
||||
.arg(
|
||||
Arg::from_usage("-o [opt]... 'some opt'")
|
||||
.number_of_values(1)
|
||||
.allow_hyphen_values(true),
|
||||
)
|
||||
.arg_from_usage("[arg] 'some arg'")
|
||||
.get_matches_from_safe(vec!["", "-o", "-2", "--", "val"]);
|
||||
assert!(r.is_ok(), "{:?}", r);
|
||||
|
@ -361,12 +363,14 @@ fn leading_hyphen_with_only_pos_follows() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature="suggestions")]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn did_you_mean() {
|
||||
assert!(test::compare_output(test::complex_app(),
|
||||
"clap-test --optio=foo",
|
||||
DYM,
|
||||
true));
|
||||
assert!(test::compare_output(
|
||||
test::complex_app(),
|
||||
"clap-test --optio=foo",
|
||||
DYM,
|
||||
true
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -408,7 +412,7 @@ fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches<'static>, clap
|
|||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_long_fail() {
|
||||
let r = issue_1105_setup(vec!["app", "--option", "--flag"]);
|
||||
let r = issue_1105_setup(vec!["app", "--option", "--flag"]);
|
||||
assert!(r.is_err());
|
||||
assert_eq!(r.unwrap_err().kind, ErrorKind::EmptyValue);
|
||||
}
|
||||
|
@ -423,7 +427,7 @@ fn issue_1105_empty_value_long_explicit() {
|
|||
|
||||
#[test]
|
||||
fn issue_1105_empty_value_long_equals() {
|
||||
let r = issue_1105_setup(vec!["app", "--option="]);
|
||||
let r = issue_1105_setup(vec!["app", "--option="]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert_eq!(m.value_of("option"), Some(""));
|
||||
|
|
|
@ -5,8 +5,10 @@ use clap::{App, Arg, ErrorKind};
|
|||
#[test]
|
||||
fn only_pos_follow() {
|
||||
let r = App::new("onlypos")
|
||||
.args(&[Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg] 'some arg'")])
|
||||
.args(&[
|
||||
Arg::from_usage("-f [flag] 'some opt'"),
|
||||
Arg::from_usage("[arg] 'some arg'"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "--", "-f"]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
|
@ -20,11 +22,13 @@ fn issue_946() {
|
|||
let r = App::new("compiletest")
|
||||
.setting(clap::AppSettings::AllowLeadingHyphen)
|
||||
.args_from_usage("--exact 'filters match exactly'")
|
||||
.arg(clap::Arg::with_name("filter")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.help("filters to apply to output"))
|
||||
.get_matches_from_safe(vec!["compiletest", "--exact"]);
|
||||
.arg(
|
||||
clap::Arg::with_name("filter")
|
||||
.index(1)
|
||||
.takes_value(true)
|
||||
.help("filters to apply to output"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["compiletest", "--exact"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let matches = r.unwrap();
|
||||
|
||||
|
@ -37,9 +41,8 @@ fn positional() {
|
|||
let r = App::new("positional")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
])
|
||||
Arg::with_name("positional").index(1),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "test"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
|
@ -50,9 +53,8 @@ fn positional() {
|
|||
let m = App::new("positional")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
])
|
||||
Arg::with_name("positional").index(1),
|
||||
])
|
||||
.get_matches_from(vec!["", "test", "--flag"]);
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
|
@ -62,10 +64,9 @@ fn positional() {
|
|||
#[test]
|
||||
fn lots_o_vals() {
|
||||
let r = App::new("opts")
|
||||
.arg(
|
||||
Arg::from_usage("[opt]... 'some pos'"),
|
||||
)
|
||||
.get_matches_from_safe(vec!["",
|
||||
.arg(Arg::from_usage("[opt]... 'some pos'"))
|
||||
.get_matches_from_safe(vec![
|
||||
"", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
|
@ -92,8 +93,8 @@ fn lots_o_vals() {
|
|||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
|
||||
]);
|
||||
"some",
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("opt"));
|
||||
|
@ -105,16 +106,17 @@ fn positional_multiple() {
|
|||
let r = App::new("positional_multiple")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
])
|
||||
Arg::with_name("positional").index(1).multiple(true),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "test1", "test2", "test3"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(&*m.values_of("positional").unwrap().collect::<Vec<_>>(), &["test1", "test2", "test3"]);
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test1", "test2", "test3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -122,16 +124,17 @@ fn positional_multiple_3() {
|
|||
let r = App::new("positional_multiple")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
.multiple(true)
|
||||
])
|
||||
Arg::with_name("positional").index(1).multiple(true),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "test1", "test2", "test3", "--flag"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(&*m.values_of("positional").unwrap().collect::<Vec<_>>(), &["test1", "test2", "test3"]);
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test1", "test2", "test3"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -139,9 +142,8 @@ fn positional_multiple_2() {
|
|||
let result = App::new("positional_multiple")
|
||||
.args(&[
|
||||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
])
|
||||
Arg::with_name("positional").index(1),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "test1", "test2", "test3"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -155,23 +157,24 @@ fn positional_possible_values() {
|
|||
Arg::from_usage("-f, --flag 'some flag'"),
|
||||
Arg::with_name("positional")
|
||||
.index(1)
|
||||
.possible_value("test123")
|
||||
])
|
||||
.possible_value("test123"),
|
||||
])
|
||||
.get_matches_from_safe(vec!["", "-f", "test123"]);
|
||||
assert!(r.is_ok(), "{:#?}", r);
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("positional"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(&*m.values_of("positional").unwrap().collect::<Vec<_>>(), &["test123"]);
|
||||
assert_eq!(
|
||||
&*m.values_of("positional").unwrap().collect::<Vec<_>>(),
|
||||
&["test123"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_positional() {
|
||||
let _ = App::new("test")
|
||||
.arg(Arg::with_name("test")
|
||||
.index(1)
|
||||
.help("testing testing"))
|
||||
.get_matches_from(vec![""]);
|
||||
.arg(Arg::with_name("test").index(1).help("testing testing"))
|
||||
.get_matches_from(vec![""]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -183,13 +186,17 @@ fn positional_hyphen_does_not_panic() {
|
|||
|
||||
#[test]
|
||||
fn single_positional_usage_string() {
|
||||
let m = App::new("test").arg_from_usage("[FILE] 'some file'").get_matches_from(vec!["test"]);
|
||||
let m = App::new("test")
|
||||
.arg_from_usage("[FILE] 'some file'")
|
||||
.get_matches_from(vec!["test"]);
|
||||
assert_eq!(m.usage(), "USAGE:\n test [FILE]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_positional_multiple_usage_string() {
|
||||
let m = App::new("test").arg_from_usage("[FILE]... 'some file'").get_matches_from(vec!["test"]);
|
||||
let m = App::new("test")
|
||||
.arg_from_usage("[FILE]... 'some file'")
|
||||
.get_matches_from(vec!["test"]);
|
||||
assert_eq!(m.usage(), "USAGE:\n test [FILE]...");
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,19 @@ use clap::{App, Arg, ErrorKind};
|
|||
#[test]
|
||||
fn posix_compatible_flags_long() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag", "--color"]);
|
||||
.arg(Arg::from_usage("--flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag", "--color"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_flags_long_rev() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color", "--flag"]);
|
||||
.arg(Arg::from_usage("--flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color", "--flag"]);
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
@ -22,16 +25,19 @@ fn posix_compatible_flags_long() {
|
|||
#[test]
|
||||
fn posix_compatible_flags_short() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("-c, --color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-f", "-c"]);
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("-c, --color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-f", "-c"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_flags_short_rev() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("-c, --color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-c", "-f"]);
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("-c, --color 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-c", "-f"]);
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
}
|
||||
|
@ -39,17 +45,20 @@ fn posix_compatible_flags_short() {
|
|||
#[test]
|
||||
fn posix_compatible_opts_long() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag", "some" ,"--color", "other"]);
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long_rev() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color", "some" ,"--flag", "other"]);
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color", "some", "--flag", "other"]);
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "other");
|
||||
|
@ -58,17 +67,20 @@ fn posix_compatible_opts_long() {
|
|||
#[test]
|
||||
fn posix_compatible_opts_long_equals() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag=some" ,"--color=other"]);
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--flag=some", "--color=other"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert_eq!(m.value_of("color").unwrap(), "other");
|
||||
assert!(!m.is_present("flag"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_long_equals_rev() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color=some" ,"--flag=other"]);
|
||||
.arg(Arg::from_usage("--flag [flag] 'some flag'").overrides_with("color"))
|
||||
.arg(Arg::from_usage("--color [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "--color=some", "--flag=other"]);
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "other");
|
||||
|
@ -77,17 +89,20 @@ fn posix_compatible_opts_long_equals() {
|
|||
#[test]
|
||||
fn posix_compatible_opts_short() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("-f [flag] 'some flag'").overrides_with("c"))
|
||||
.arg(Arg::from_usage("-c [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-f", "some", "-c", "other"]);
|
||||
.arg(Arg::from_usage("-f [flag] 'some flag'").overrides_with("c"))
|
||||
.arg(Arg::from_usage("-c [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-f", "some", "-c", "other"]);
|
||||
assert!(m.is_present("c"));
|
||||
assert_eq!(m.value_of("c").unwrap(), "other");
|
||||
assert!(!m.is_present("f"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn posix_compatible_opts_short_rev() {
|
||||
let m = App::new("posix")
|
||||
.arg(Arg::from_usage("-f [flag] 'some flag'").overrides_with("c"))
|
||||
.arg(Arg::from_usage("-c [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-c", "some", "-f", "other"]);
|
||||
.arg(Arg::from_usage("-f [flag] 'some flag'").overrides_with("c"))
|
||||
.arg(Arg::from_usage("-c [color] 'some other flag'"))
|
||||
.get_matches_from(vec!["", "-c", "some", "-f", "other"]);
|
||||
assert!(!m.is_present("c"));
|
||||
assert!(m.is_present("f"));
|
||||
assert_eq!(m.value_of("f").unwrap(), "other");
|
||||
|
@ -96,11 +111,9 @@ fn posix_compatible_opts_short() {
|
|||
#[test]
|
||||
fn conflict_overriden() {
|
||||
let m = App::new("conflict_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from(vec!["", "-f", "-c", "-d"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
|
@ -110,11 +123,9 @@ fn conflict_overriden() {
|
|||
#[test]
|
||||
fn conflict_overriden_2() {
|
||||
let result = App::new("conflict_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from_safe(vec!["", "-f", "-d", "-c"]);
|
||||
assert!(result.is_ok());
|
||||
let m = result.unwrap();
|
||||
|
@ -126,11 +137,9 @@ fn conflict_overriden_2() {
|
|||
#[test]
|
||||
fn conflict_overriden_3() {
|
||||
let result = App::new("conflict_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from_safe(vec!["", "-d", "-c", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -140,11 +149,9 @@ fn conflict_overriden_3() {
|
|||
#[test]
|
||||
fn conflict_overriden_4() {
|
||||
let m = App::new("conflict_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").conflicts_with("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from(vec!["", "-d", "-f", "-c"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
|
@ -154,11 +161,8 @@ fn conflict_overriden_4() {
|
|||
#[test]
|
||||
fn pos_required_overridden_by_flag() {
|
||||
let result = App::new("require_overriden")
|
||||
.arg(Arg::with_name("pos")
|
||||
.index(1)
|
||||
.required(true))
|
||||
.arg(Arg::from_usage("-c, --color 'some flag'")
|
||||
.overrides_with("pos"))
|
||||
.arg(Arg::with_name("pos").index(1).required(true))
|
||||
.arg(Arg::from_usage("-c, --color 'some flag'").overrides_with("pos"))
|
||||
.get_matches_from_safe(vec!["", "test", "-c"]);
|
||||
assert!(result.is_ok(), "{:?}", result.unwrap_err());
|
||||
}
|
||||
|
@ -166,10 +170,8 @@ fn pos_required_overridden_by_flag() {
|
|||
#[test]
|
||||
fn require_overriden_2() {
|
||||
let m = App::new("require_overriden")
|
||||
.arg(Arg::with_name("req_pos")
|
||||
.required(true))
|
||||
.arg(Arg::from_usage("-c, --color 'other flag'")
|
||||
.overrides_with("req_pos"))
|
||||
.arg(Arg::with_name("req_pos").required(true))
|
||||
.arg(Arg::from_usage("-c, --color 'other flag'").overrides_with("req_pos"))
|
||||
.get_matches_from(vec!["", "-c", "req_pos"]);
|
||||
assert!(!m.is_present("color"));
|
||||
assert!(m.is_present("req_pos"));
|
||||
|
@ -178,11 +180,9 @@ fn require_overriden_2() {
|
|||
#[test]
|
||||
fn require_overriden_3() {
|
||||
let m = App::new("require_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.requires("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").requires("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from(vec!["", "-f", "-c"]);
|
||||
assert!(m.is_present("color"));
|
||||
assert!(!m.is_present("flag"));
|
||||
|
@ -192,11 +192,9 @@ fn require_overriden_3() {
|
|||
#[test]
|
||||
fn require_overriden_4() {
|
||||
let result = App::new("require_overriden")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'")
|
||||
.requires("debug"))
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").requires("debug"))
|
||||
.arg(Arg::from_usage("-d, --debug 'other flag'"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'")
|
||||
.overrides_with("flag"))
|
||||
.arg(Arg::from_usage("-c, --color 'third flag'").overrides_with("flag"))
|
||||
.get_matches_from_safe(vec!["", "-c", "-f"]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
|
|
@ -4,27 +4,26 @@ extern crate regex;
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
include!("../clap-test.rs");
|
||||
use clap::{App, Arg, SubCommand, ArgMatches};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
|
||||
fn get_app() -> App<'static, 'static> {
|
||||
App::new("myprog")
|
||||
.arg(Arg::with_name("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help(
|
||||
"Specifies something needed by the subcommands",
|
||||
)
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"))
|
||||
.arg(Arg::with_name("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help(
|
||||
"Specifies something needed by the subcommands",
|
||||
)
|
||||
.multiple(true)
|
||||
.global(true))
|
||||
.subcommand(SubCommand::with_name("outer")
|
||||
.subcommand(SubCommand::with_name("inner")))
|
||||
.arg(
|
||||
Arg::with_name("GLOBAL_ARG")
|
||||
.long("global-arg")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.global(true)
|
||||
.takes_value(true)
|
||||
.default_value("default_value"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("GLOBAL_FLAG")
|
||||
.long("global-flag")
|
||||
.help("Specifies something needed by the subcommands")
|
||||
.multiple(true)
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(SubCommand::with_name("outer").subcommand(SubCommand::with_name("inner")))
|
||||
}
|
||||
|
||||
fn get_matches(app: App<'static, 'static>, argv: &'static str) -> ArgMatches<'static> {
|
||||
|
@ -32,22 +31,31 @@ mod tests {
|
|||
}
|
||||
|
||||
fn get_outer_matches<'a>(m: &'a ArgMatches<'static>) -> &'a ArgMatches<'static> {
|
||||
m.subcommand_matches("outer").expect("could not access outer subcommand")
|
||||
m.subcommand_matches("outer")
|
||||
.expect("could not access outer subcommand")
|
||||
}
|
||||
|
||||
fn get_inner_matches<'a>(m: &'a ArgMatches<'static>) -> &'a ArgMatches<'static> {
|
||||
get_outer_matches(m).subcommand_matches("inner").expect("could not access inner subcommand")
|
||||
get_outer_matches(m)
|
||||
.subcommand_matches("inner")
|
||||
.expect("could not access inner subcommand")
|
||||
}
|
||||
|
||||
fn top_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches<'static>, val: T) -> bool {
|
||||
m.value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
fn inner_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches<'static>, val: T) -> bool {
|
||||
fn inner_can_access_arg<T: Into<Option<&'static str>>>(
|
||||
m: &ArgMatches<'static>,
|
||||
val: T,
|
||||
) -> bool {
|
||||
get_inner_matches(m).value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
fn outer_can_access_arg<T: Into<Option<&'static str>>>(m: &ArgMatches<'static>, val: T) -> bool {
|
||||
fn outer_can_access_arg<T: Into<Option<&'static str>>>(
|
||||
m: &ArgMatches<'static>,
|
||||
val: T,
|
||||
) -> bool {
|
||||
get_outer_matches(m).value_of("GLOBAL_ARG") == val.into()
|
||||
}
|
||||
|
||||
|
|
421
tests/require.rs
421
tests/require.rs
|
@ -3,7 +3,7 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, Arg, ErrorKind, ArgGroup};
|
||||
use clap::{App, Arg, ArgGroup, ErrorKind};
|
||||
|
||||
static REQUIRE_EQUALS: &'static str = "error: The following required arguments were not provided:
|
||||
--opt=<FILE>
|
||||
|
@ -22,7 +22,8 @@ USAGE:
|
|||
|
||||
For more information try --help";
|
||||
|
||||
static COND_REQ_IN_USAGE: &'static str = "error: The following required arguments were not provided:
|
||||
static COND_REQ_IN_USAGE: &'static str =
|
||||
"error: The following required arguments were not provided:
|
||||
--output <output>
|
||||
|
||||
USAGE:
|
||||
|
@ -77,9 +78,7 @@ fn option_required_2() {
|
|||
#[test]
|
||||
fn positional_required() {
|
||||
let result = App::new("positional_required")
|
||||
.arg(Arg::with_name("flag")
|
||||
.index(1)
|
||||
.required(true))
|
||||
.arg(Arg::with_name("flag").index(1).required(true))
|
||||
.get_matches_from_safe(vec![""]);
|
||||
assert!(result.is_err());
|
||||
let err = result.err().unwrap();
|
||||
|
@ -89,9 +88,7 @@ fn positional_required() {
|
|||
#[test]
|
||||
fn positional_required_2() {
|
||||
let m = App::new("positional_required")
|
||||
.arg(Arg::with_name("flag")
|
||||
.index(1)
|
||||
.required(true))
|
||||
.arg(Arg::with_name("flag").index(1).required(true))
|
||||
.get_matches_from(vec!["", "someval"]);
|
||||
assert!(m.is_present("flag"));
|
||||
assert_eq!(m.value_of("flag").unwrap(), "someval");
|
||||
|
@ -101,10 +98,12 @@ fn positional_required_2() {
|
|||
fn group_required() {
|
||||
let result = App::new("group_required")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(
|
||||
ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"),
|
||||
)
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from_safe(vec!["", "-f"]);
|
||||
|
@ -117,10 +116,12 @@ fn group_required() {
|
|||
fn group_required_2() {
|
||||
let m = App::new("group_required")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(
|
||||
ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"),
|
||||
)
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from(vec!["", "-f", "--some"]);
|
||||
|
@ -133,10 +134,12 @@ fn group_required_2() {
|
|||
fn group_required_3() {
|
||||
let m = App::new("group_required")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(
|
||||
ArgGroup::with_name("gr")
|
||||
.required(true)
|
||||
.arg("some")
|
||||
.arg("other"),
|
||||
)
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from(vec!["", "-f", "--other"]);
|
||||
|
@ -149,9 +152,7 @@ fn group_required_3() {
|
|||
fn arg_require_group() {
|
||||
let result = App::new("arg_require_group")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").requires("gr"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(ArgGroup::with_name("gr").arg("some").arg("other"))
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from_safe(vec!["", "-f"]);
|
||||
|
@ -164,9 +165,7 @@ fn arg_require_group() {
|
|||
fn arg_require_group_2() {
|
||||
let m = App::new("arg_require_group")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").requires("gr"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(ArgGroup::with_name("gr").arg("some").arg("other"))
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from(vec!["", "-f", "--some"]);
|
||||
|
@ -179,9 +178,7 @@ fn arg_require_group_2() {
|
|||
fn arg_require_group_3() {
|
||||
let m = App::new("arg_require_group")
|
||||
.arg(Arg::from_usage("-f, --flag 'some flag'").requires("gr"))
|
||||
.group(ArgGroup::with_name("gr")
|
||||
.arg("some")
|
||||
.arg("other"))
|
||||
.group(ArgGroup::with_name("gr").arg("some").arg("other"))
|
||||
.arg(Arg::from_usage("--some 'some arg'"))
|
||||
.arg(Arg::from_usage("--other 'other arg'"))
|
||||
.get_matches_from(vec!["", "-f", "--other"]);
|
||||
|
@ -195,16 +192,24 @@ fn arg_require_group_3() {
|
|||
#[test]
|
||||
fn issue_753() {
|
||||
let m = App::new("test")
|
||||
.arg(Arg::from_usage("-l, --list 'List available interfaces (and stop there)'"))
|
||||
.arg(Arg::from_usage("-i, --iface=[INTERFACE] 'Ethernet interface for fetching NTP packets'")
|
||||
.required_unless("list"))
|
||||
.arg(Arg::from_usage("-f, --file=[TESTFILE] 'Fetch NTP packets from pcap file'")
|
||||
.conflicts_with("iface")
|
||||
.required_unless("list"))
|
||||
.arg(Arg::from_usage("-s, --server=[SERVER_IP] 'NTP server IP address'")
|
||||
.required_unless("list"))
|
||||
.arg(Arg::from_usage("-p, --port=[SERVER_PORT] 'NTP server port'")
|
||||
.default_value("123"))
|
||||
.arg(Arg::from_usage(
|
||||
"-l, --list 'List available interfaces (and stop there)'",
|
||||
))
|
||||
.arg(
|
||||
Arg::from_usage(
|
||||
"-i, --iface=[INTERFACE] 'Ethernet interface for fetching NTP packets'",
|
||||
).required_unless("list"),
|
||||
)
|
||||
.arg(
|
||||
Arg::from_usage("-f, --file=[TESTFILE] 'Fetch NTP packets from pcap file'")
|
||||
.conflicts_with("iface")
|
||||
.required_unless("list"),
|
||||
)
|
||||
.arg(
|
||||
Arg::from_usage("-s, --server=[SERVER_IP] 'NTP server IP address'")
|
||||
.required_unless("list"),
|
||||
)
|
||||
.arg(Arg::from_usage("-p, --port=[SERVER_PORT] 'NTP server port'").default_value("123"))
|
||||
.get_matches_from_safe(vec!["test", "--list"]);
|
||||
assert!(m.is_ok());
|
||||
}
|
||||
|
@ -212,10 +217,12 @@ fn issue_753() {
|
|||
#[test]
|
||||
fn required_unless() {
|
||||
let res = App::new("unlesstest")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.get_matches_from_safe(vec!["unlesstest", "--debug"]);
|
||||
|
||||
|
@ -228,10 +235,12 @@ fn required_unless() {
|
|||
#[test]
|
||||
fn required_unless_err() {
|
||||
let res = App::new("unlesstest")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.get_matches_from_safe(vec!["unlesstest"]);
|
||||
|
||||
|
@ -244,14 +253,14 @@ fn required_unless_err() {
|
|||
#[test]
|
||||
fn required_unless_all() {
|
||||
let res = App::new("unlessall")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessall", "--debug", "-i", "file"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -264,14 +273,14 @@ fn required_unless_all() {
|
|||
#[test]
|
||||
fn required_unless_all_err() {
|
||||
let res = App::new("unlessall")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessall", "--debug"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
|
@ -283,14 +292,14 @@ fn required_unless_all_err() {
|
|||
#[test]
|
||||
fn required_unless_one() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessone", "--debug"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -304,14 +313,14 @@ fn required_unless_one_2() {
|
|||
// This tests that the required_unless_one works when the second arg in the array is used
|
||||
// instead of the first.
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessone", "-i", "file"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -329,8 +338,9 @@ fn required_unless_one_works_with_short() {
|
|||
.arg(
|
||||
Arg::with_name("x")
|
||||
.short("x")
|
||||
.required_unless_one(&["a", "b"])
|
||||
).get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
.required_unless_one(&["a", "b"]),
|
||||
)
|
||||
.get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
@ -343,8 +353,9 @@ fn required_unless_one_works_with_short_err() {
|
|||
.arg(
|
||||
Arg::with_name("x")
|
||||
.short("x")
|
||||
.required_unless_one(&["a", "b"])
|
||||
).get_matches_from_safe(vec!["unlessone"]);
|
||||
.required_unless_one(&["a", "b"]),
|
||||
)
|
||||
.get_matches_from_safe(vec!["unlessone"]);
|
||||
|
||||
assert!(!res.is_ok());
|
||||
}
|
||||
|
@ -354,10 +365,8 @@ fn required_unless_one_works_without() {
|
|||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("a").conflicts_with("b").short("a"))
|
||||
.arg(Arg::with_name("b").short("b"))
|
||||
.arg(
|
||||
Arg::with_name("x")
|
||||
.required_unless_one(&["a", "b"])
|
||||
).get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
.arg(Arg::with_name("x").required_unless_one(&["a", "b"]))
|
||||
.get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
@ -370,8 +379,9 @@ fn required_unless_one_works_with_long() {
|
|||
.arg(
|
||||
Arg::with_name("x")
|
||||
.long("x_is_the_option")
|
||||
.required_unless_one(&["a", "b"])
|
||||
).get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
.required_unless_one(&["a", "b"]),
|
||||
)
|
||||
.get_matches_from_safe(vec!["unlessone", "-a"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
@ -379,14 +389,14 @@ fn required_unless_one_works_with_long() {
|
|||
#[test]
|
||||
fn required_unless_one_1() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessone", "--debug"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -399,14 +409,14 @@ fn required_unless_one_1() {
|
|||
#[test]
|
||||
fn required_unless_one_err() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("dbg").long("debug"))
|
||||
.arg(Arg::with_name("infile")
|
||||
.short("i")
|
||||
.takes_value(true))
|
||||
.arg(Arg::with_name("infile").short("i").takes_value(true))
|
||||
.get_matches_from_safe(vec!["unlessone"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
|
@ -415,7 +425,12 @@ fn required_unless_one_err() {
|
|||
|
||||
#[test]
|
||||
fn missing_required_output() {
|
||||
assert!(test::compare_output(test::complex_app(), "clap-test -F", MISSING_REQ, true));
|
||||
assert!(test::compare_output(
|
||||
test::complex_app(),
|
||||
"clap-test -F",
|
||||
MISSING_REQ,
|
||||
true
|
||||
));
|
||||
}
|
||||
|
||||
// Conditional external requirements
|
||||
|
@ -423,10 +438,12 @@ fn missing_required_output() {
|
|||
#[test]
|
||||
fn requires_if_present_val() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.requires_if("my.cfg", "extra")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.requires_if("my.cfg", "extra")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").long("extra"))
|
||||
.get_matches_from_safe(vec!["unlessone", "--config=my.cfg"]);
|
||||
|
||||
|
@ -437,10 +454,12 @@ fn requires_if_present_val() {
|
|||
#[test]
|
||||
fn requires_if_present_mult() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.requires_ifs(&[("my.cfg", "extra"), ("other.cfg", "other")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.requires_ifs(&[("my.cfg", "extra"), ("other.cfg", "other")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").long("extra"))
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches_from_safe(vec!["unlessone", "--config=other.cfg"]);
|
||||
|
@ -452,10 +471,12 @@ fn requires_if_present_mult() {
|
|||
#[test]
|
||||
fn requires_if_present_mult_pass() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.requires_ifs(&[("my.cfg", "extra"), ("other.cfg", "other")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.requires_ifs(&[("my.cfg", "extra"), ("other.cfg", "other")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").long("extra"))
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches_from_safe(vec!["unlessone", "--config=some.cfg"]);
|
||||
|
@ -467,10 +488,12 @@ fn requires_if_present_mult_pass() {
|
|||
#[test]
|
||||
fn requires_if_present_val_no_present_pass() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.requires_if("my.cfg", "extra")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.requires_if("my.cfg", "extra")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").long("extra"))
|
||||
.get_matches_from_safe(vec!["unlessone"]);
|
||||
|
||||
|
@ -482,13 +505,13 @@ fn requires_if_present_val_no_present_pass() {
|
|||
#[test]
|
||||
fn required_if_val_present_pass() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.get_matches_from_safe(vec!["ri", "--extra", "val", "--config", "my.cfg"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -497,13 +520,13 @@ fn required_if_val_present_pass() {
|
|||
#[test]
|
||||
fn required_if_val_present_fail() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.get_matches_from_safe(vec!["ri", "--extra", "val"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
|
@ -516,36 +539,44 @@ fn required_if_val_present_fail_error_output() {
|
|||
.version("1.0")
|
||||
.author("F0x06")
|
||||
.about("Arg test")
|
||||
.arg(Arg::with_name("target")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.possible_values(&["file", "stdout"])
|
||||
.long("target"))
|
||||
.arg(Arg::with_name("input")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.long("input"))
|
||||
.arg(Arg::with_name("output")
|
||||
.takes_value(true)
|
||||
.required_if("target", "file")
|
||||
.long("output"));
|
||||
.arg(
|
||||
Arg::with_name("target")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.possible_values(&["file", "stdout"])
|
||||
.long("target"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("input")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.long("input"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("output")
|
||||
.takes_value(true)
|
||||
.required_if("target", "file")
|
||||
.long("output"),
|
||||
);
|
||||
|
||||
assert!(test::compare_output(app,
|
||||
"test --input somepath --target file",
|
||||
COND_REQ_IN_USAGE,
|
||||
true));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"test --input somepath --target file",
|
||||
COND_REQ_IN_USAGE,
|
||||
true
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_if_wrong_val() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_if("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.get_matches_from_safe(vec!["ri", "--extra", "other"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -554,16 +585,14 @@ fn required_if_wrong_val() {
|
|||
#[test]
|
||||
fn required_ifs_val_present_pass() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("option")
|
||||
.takes_value(true)
|
||||
.long("option"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("option").takes_value(true).long("option"))
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.get_matches_from_safe(vec!["ri", "--option", "spec", "--config", "my.cfg"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -573,16 +602,14 @@ fn required_ifs_val_present_pass() {
|
|||
#[test]
|
||||
fn required_ifs_val_present_fail() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(Arg::with_name("option")
|
||||
.takes_value(true)
|
||||
.long("option"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.arg(Arg::with_name("option").takes_value(true).long("option"))
|
||||
.get_matches_from_safe(vec!["ri", "--option", "spec"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
|
@ -592,16 +619,14 @@ fn required_ifs_val_present_fail() {
|
|||
#[test]
|
||||
fn required_ifs_wrong_val() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(Arg::with_name("option")
|
||||
.takes_value(true)
|
||||
.long("option"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.arg(Arg::with_name("option").takes_value(true).long("option"))
|
||||
.get_matches_from_safe(vec!["ri", "--option", "other"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
|
@ -610,16 +635,14 @@ fn required_ifs_wrong_val() {
|
|||
#[test]
|
||||
fn required_ifs_wrong_val_mult_fail() {
|
||||
let res = App::new("ri")
|
||||
.arg(Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"))
|
||||
.arg(Arg::with_name("extra")
|
||||
.takes_value(true)
|
||||
.long("extra"))
|
||||
.arg(Arg::with_name("option")
|
||||
.takes_value(true)
|
||||
.long("option"))
|
||||
.arg(
|
||||
Arg::with_name("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
.arg(Arg::with_name("extra").takes_value(true).long("extra"))
|
||||
.arg(Arg::with_name("option").takes_value(true).long("option"))
|
||||
.get_matches_from_safe(vec!["ri", "--extra", "other", "--option", "spec"]);
|
||||
|
||||
assert!(res.is_err());
|
||||
|
@ -628,16 +651,14 @@ fn required_ifs_wrong_val_mult_fail() {
|
|||
|
||||
#[test]
|
||||
fn require_eq() {
|
||||
let app = App::new("clap-test")
|
||||
.version("v1.4.8")
|
||||
.arg(
|
||||
Arg::with_name("opt")
|
||||
let app = App::new("clap-test").version("v1.4.8").arg(
|
||||
Arg::with_name("opt")
|
||||
.long("opt")
|
||||
.short("o")
|
||||
.required(true)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
.help("some")
|
||||
);
|
||||
.help("some"),
|
||||
);
|
||||
assert!(test::compare_output(app, "clap-test", REQUIRE_EQUALS, true));
|
||||
}
|
|
@ -3,7 +3,7 @@ extern crate regex;
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
use clap::{App, Arg, SubCommand, ErrorKind};
|
||||
use clap::{App, Arg, ErrorKind, SubCommand};
|
||||
|
||||
static VISIBLE_ALIAS_HELP: &'static str = "clap-test 2.6
|
||||
|
||||
|
@ -43,7 +43,8 @@ USAGE:
|
|||
For more information try --help";
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
static DYM_ARG: &'static str = "error: Found argument '--subcm' which wasn't expected, or isn't valid in this context
|
||||
static DYM_ARG: &'static str =
|
||||
"error: Found argument '--subcm' which wasn't expected, or isn't valid in this context
|
||||
\tDid you mean to put '--subcmdarg' after the subcommand 'subcmd'?
|
||||
|
||||
USAGE:
|
||||
|
@ -54,12 +55,15 @@ For more information try --help";
|
|||
#[test]
|
||||
fn subcommand() {
|
||||
let m = App::new("test")
|
||||
.subcommand(SubCommand::with_name("some")
|
||||
.arg(Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing")))
|
||||
.subcommand(
|
||||
SubCommand::with_name("some").arg(
|
||||
Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches_from(vec!["myprog", "some", "--test", "testing"]);
|
||||
|
||||
|
@ -72,12 +76,15 @@ fn subcommand() {
|
|||
#[test]
|
||||
fn subcommand_none_given() {
|
||||
let m = App::new("test")
|
||||
.subcommand(SubCommand::with_name("some")
|
||||
.arg(Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing")))
|
||||
.subcommand(
|
||||
SubCommand::with_name("some").arg(
|
||||
Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing"),
|
||||
),
|
||||
)
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches_from(vec![""]);
|
||||
|
||||
|
@ -88,14 +95,14 @@ fn subcommand_none_given() {
|
|||
fn subcommand_multiple() {
|
||||
let m = App::new("test")
|
||||
.subcommands(vec![
|
||||
SubCommand::with_name("some")
|
||||
.arg(Arg::with_name("test")
|
||||
SubCommand::with_name("some").arg(
|
||||
Arg::with_name("test")
|
||||
.short("t")
|
||||
.long("test")
|
||||
.takes_value(true)
|
||||
.help("testing testing")),
|
||||
SubCommand::with_name("add")
|
||||
.arg(Arg::with_name("roster").short("r"))
|
||||
.help("testing testing"),
|
||||
),
|
||||
SubCommand::with_name("add").arg(Arg::with_name("roster").short("r")),
|
||||
])
|
||||
.arg(Arg::with_name("other").long("other"))
|
||||
.get_matches_from(vec!["myprog", "some", "--test", "testing"]);
|
||||
|
@ -111,68 +118,74 @@ fn subcommand_multiple() {
|
|||
#[test]
|
||||
fn single_alias() {
|
||||
let m = App::new("myprog")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.alias("do-stuff"))
|
||||
.get_matches_from(vec!["myprog", "do-stuff"]);
|
||||
.subcommand(SubCommand::with_name("test").alias("do-stuff"))
|
||||
.get_matches_from(vec!["myprog", "do-stuff"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_aliases() {
|
||||
let m = App::new("myprog")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.aliases(&["do-stuff", "test-stuff"]))
|
||||
.get_matches_from(vec!["myprog", "test-stuff"]);
|
||||
.subcommand(SubCommand::with_name("test").aliases(&["do-stuff", "test-stuff"]))
|
||||
.get_matches_from(vec!["myprog", "test-stuff"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature="suggestions")]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output() {
|
||||
let app = App::new("dym")
|
||||
.subcommand(SubCommand::with_name("subcmd"));
|
||||
let app = App::new("dym").subcommand(SubCommand::with_name("subcmd"));
|
||||
assert!(test::compare_output(app, "dym subcm", DYM_SUBCMD, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature="suggestions")]
|
||||
#[cfg(feature = "suggestions")]
|
||||
fn subcmd_did_you_mean_output_arg() {
|
||||
let app = App::new("dym")
|
||||
.subcommand(SubCommand::with_name("subcmd")
|
||||
.arg_from_usage("-s --subcmdarg [subcmdarg] 'tests'") );
|
||||
let app = App::new("dym").subcommand(
|
||||
SubCommand::with_name("subcmd").arg_from_usage("-s --subcmdarg [subcmdarg] 'tests'"),
|
||||
);
|
||||
assert!(test::compare_output(app, "dym --subcm foo", DYM_ARG, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias_help() {
|
||||
let m = App::new("myprog")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.alias("do-stuff"))
|
||||
.get_matches_from_safe(vec!["myprog", "help", "do-stuff"]);
|
||||
.subcommand(SubCommand::with_name("test").alias("do-stuff"))
|
||||
.get_matches_from_safe(vec!["myprog", "help", "do-stuff"]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_aliases_help_output() {
|
||||
let app = App::new("clap-test")
|
||||
.version("2.6")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
let app = App::new("clap-test").version("2.6").subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("Some help")
|
||||
.alias("invisible")
|
||||
.visible_alias("dongle")
|
||||
.visible_alias("done"));
|
||||
assert!(test::compare_output(app, "clap-test --help", VISIBLE_ALIAS_HELP, false));
|
||||
.visible_alias("done"),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
VISIBLE_ALIAS_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invisible_aliases_help_output() {
|
||||
let app = App::new("clap-test")
|
||||
.version("2.6")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
let app = App::new("clap-test").version("2.6").subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("Some help")
|
||||
.alias("invisible"));
|
||||
assert!(test::compare_output(app, "clap-test --help", INVISIBLE_ALIAS_HELP, false));
|
||||
.alias("invisible"),
|
||||
);
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"clap-test --help",
|
||||
INVISIBLE_ALIAS_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -5,8 +5,8 @@ use clap::{App, SubCommand};
|
|||
|
||||
include!("../clap-test.rs");
|
||||
|
||||
static EXAMPLE1_TMPL_S : &'static str = include_str!("example1_tmpl_simple.txt");
|
||||
static EXAMPLE1_TMPS_F : &'static str = include_str!("example1_tmpl_full.txt");
|
||||
static EXAMPLE1_TMPL_S: &'static str = include_str!("example1_tmpl_simple.txt");
|
||||
static EXAMPLE1_TMPS_F: &'static str = include_str!("example1_tmpl_full.txt");
|
||||
|
||||
static CUSTOM_TEMPL_HELP: &'static str = "MyApp 1.0
|
||||
Kevin K. <kbknapp@gmail.com>
|
||||
|
@ -52,53 +52,78 @@ SUBCOMMANDS:
|
|||
#[test]
|
||||
fn with_template() {
|
||||
let app = app_example1().template(EXAMPLE1_TMPL_S);
|
||||
assert!(test::compare_output(app, "MyApp --help", SIMPLE_TEMPLATE, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"MyApp --help",
|
||||
SIMPLE_TEMPLATE,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_template() {
|
||||
let app = app_example1().template(EXAMPLE1_TMPS_F);
|
||||
assert!(test::compare_output(app, "MyApp --help", CUSTOM_TEMPL_HELP, false));
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"MyApp --help",
|
||||
CUSTOM_TEMPL_HELP,
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_empty() {
|
||||
let app = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("");
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("");
|
||||
assert!(test::compare_output(app, "MyApp --help", "", false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_notag() {
|
||||
let app = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("test no tag test");
|
||||
assert!(test::compare_output(app, "MyApp --help", "test no tag test", false));
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("test no tag test");
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"MyApp --help",
|
||||
"test no tag test",
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_unknowntag() {
|
||||
let app = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("test {unknown_tag} test");
|
||||
assert!(test::compare_output(app, "MyApp --help", "test {unknown_tag} test", false));
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("test {unknown_tag} test");
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"MyApp --help",
|
||||
"test {unknown_tag} test",
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_author_version() {
|
||||
let app = App::new("MyApp")
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("{author}\n{version}\n{about}\n{bin}");
|
||||
assert!(test::compare_output(app, "MyApp --help", "Kevin K. <kbknapp@gmail.com>\n1.0\nDoes awesome things\nMyApp", false));
|
||||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.template("{author}\n{version}\n{about}\n{bin}");
|
||||
assert!(test::compare_output(
|
||||
app,
|
||||
"MyApp --help",
|
||||
"Kevin K. <kbknapp@gmail.com>\n1.0\nDoes awesome things\nMyApp",
|
||||
false
|
||||
));
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
@ -108,10 +133,14 @@ fn app_example1<'b, 'c>() -> App<'b, 'c> {
|
|||
.version("1.0")
|
||||
.author("Kevin K. <kbknapp@gmail.com>")
|
||||
.about("Does awesome things")
|
||||
.args_from_usage("-c, --config=[FILE] 'Sets a custom config file'
|
||||
.args_from_usage(
|
||||
"-c, --config=[FILE] 'Sets a custom config file'
|
||||
<output> 'Sets an optional output file'
|
||||
-d... 'Turn debugging information on'")
|
||||
.subcommand(SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"))
|
||||
-d... 'Turn debugging information on'",
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("test")
|
||||
.about("does testing things")
|
||||
.arg_from_usage("-l, --list 'lists test values'"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -101,7 +101,12 @@ pub fn check_complex_output(args: &str, out: &str) {
|
|||
|
||||
if matches.is_present("option") {
|
||||
if let Some(v) = matches.value_of("option") {
|
||||
writeln!(w, "option present {} times with value: {}",matches.occurrences_of("option"), v).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option present {} times with value: {}",
|
||||
matches.occurrences_of("option"),
|
||||
v
|
||||
).unwrap();
|
||||
}
|
||||
if let Some(ov) = matches.values_of("option") {
|
||||
for o in ov {
|
||||
|
@ -120,29 +125,50 @@ pub fn check_complex_output(args: &str, out: &str) {
|
|||
|
||||
if matches.is_present("flag2") {
|
||||
writeln!(w, "flag2 present").unwrap();
|
||||
writeln!(w, "option2 present with value of: {}", matches.value_of("long-option-2").unwrap()).unwrap();
|
||||
writeln!(w, "positional2 present with value of: {}", matches.value_of("positional2").unwrap()).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option2 present with value of: {}",
|
||||
matches.value_of("long-option-2").unwrap()
|
||||
).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"positional2 present with value of: {}",
|
||||
matches.value_of("positional2").unwrap()
|
||||
).unwrap();
|
||||
} else {
|
||||
writeln!(w, "flag2 NOT present").unwrap();
|
||||
writeln!(w, "option2 maybe present with value of: {}", matches.value_of("long-option-2").unwrap_or("Nothing")).unwrap();
|
||||
writeln!(w, "positional2 maybe present with value of: {}", matches.value_of("positional2").unwrap_or("Nothing")).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option2 maybe present with value of: {}",
|
||||
matches.value_of("long-option-2").unwrap_or("Nothing")
|
||||
).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"positional2 maybe present with value of: {}",
|
||||
matches.value_of("positional2").unwrap_or("Nothing")
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
let _ = match matches.value_of("Option3").unwrap_or("") {
|
||||
"fast" => writeln!(w, "option3 present quickly"),
|
||||
"slow" => writeln!(w, "option3 present slowly"),
|
||||
_ => writeln!(w, "option3 NOT present")
|
||||
_ => writeln!(w, "option3 NOT present"),
|
||||
};
|
||||
|
||||
let _ = match matches.value_of("positional3").unwrap_or("") {
|
||||
"vi" => writeln!(w, "positional3 present in vi mode"),
|
||||
"emacs" => writeln!(w, "positional3 present in emacs mode"),
|
||||
_ => writeln!(w, "positional3 NOT present")
|
||||
_ => writeln!(w, "positional3 NOT present"),
|
||||
};
|
||||
|
||||
if matches.is_present("option") {
|
||||
if let Some(v) = matches.value_of("option") {
|
||||
writeln!(w, "option present {} times with value: {}",matches.occurrences_of("option"), v).unwrap();
|
||||
writeln!(
|
||||
w,
|
||||
"option present {} times with value: {}",
|
||||
matches.occurrences_of("option"),
|
||||
v
|
||||
).unwrap();
|
||||
}
|
||||
if let Some(ov) = matches.values_of("option") {
|
||||
for o in ov {
|
||||
|
@ -268,22 +294,27 @@ fn test_enums() {
|
|||
|
||||
#[test]
|
||||
fn create_app() {
|
||||
let _ =
|
||||
App::new("test").version("1.0").author("kevin").about("does awesome things").get_matches_from(vec![""]);
|
||||
let _ = App::new("test")
|
||||
.version("1.0")
|
||||
.author("kevin")
|
||||
.about("does awesome things")
|
||||
.get_matches_from(vec![""]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_multiple_arg() {
|
||||
let _ = App::new("test")
|
||||
.args(&mut [
|
||||
Arg::with_name("test").short("s"),
|
||||
Arg::with_name("test2").short("l")])
|
||||
.get_matches_from(vec![""]);
|
||||
.args(&mut [
|
||||
Arg::with_name("test").short("s"),
|
||||
Arg::with_name("test2").short("l"),
|
||||
])
|
||||
.get_matches_from(vec![""]);
|
||||
}
|
||||
#[test]
|
||||
fn flag_x2_opt() {
|
||||
check_complex_output("clap-test value -f -f -o some",
|
||||
"flag present 2 times
|
||||
check_complex_output(
|
||||
"clap-test value -f -f -o some",
|
||||
"flag present 2 times
|
||||
option present 1 times with value: some
|
||||
An option: some
|
||||
positional present with value: value
|
||||
|
@ -296,13 +327,12 @@ option present 1 times with value: some
|
|||
An option: some
|
||||
positional present with value: value
|
||||
subcmd NOT present
|
||||
");
|
||||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_opt_x2_pos() {
|
||||
check_complex_output("clap-test value --option some --option other", O2P);
|
||||
}
|
||||
fn long_opt_x2_pos() { check_complex_output("clap-test value --option some --option other", O2P); }
|
||||
|
||||
#[test]
|
||||
fn long_opt_eq_x2_pos() {
|
||||
|
@ -310,29 +340,19 @@ fn long_opt_eq_x2_pos() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn short_opt_x2_pos() {
|
||||
check_complex_output("clap-test value -o some -o other", O2P);
|
||||
}
|
||||
fn short_opt_x2_pos() { check_complex_output("clap-test value -o some -o other", O2P); }
|
||||
|
||||
#[test]
|
||||
fn short_opt_eq_x2_pos() {
|
||||
check_complex_output("clap-test value -o=some -o=other", O2P);
|
||||
}
|
||||
fn short_opt_eq_x2_pos() { check_complex_output("clap-test value -o=some -o=other", O2P); }
|
||||
|
||||
#[test]
|
||||
fn short_flag_x2_comb_short_opt_pos() {
|
||||
check_complex_output("clap-test value -ff -o some", F2OP);
|
||||
}
|
||||
fn short_flag_x2_comb_short_opt_pos() { check_complex_output("clap-test value -ff -o some", F2OP); }
|
||||
|
||||
#[test]
|
||||
fn short_flag_short_opt_pos() {
|
||||
check_complex_output("clap-test value -f -o some", FOP);
|
||||
}
|
||||
fn short_flag_short_opt_pos() { check_complex_output("clap-test value -f -o some", FOP); }
|
||||
|
||||
#[test]
|
||||
fn long_flag_long_opt_pos() {
|
||||
check_complex_output("clap-test value --flag --option some", FOP);
|
||||
}
|
||||
fn long_flag_long_opt_pos() { check_complex_output("clap-test value --flag --option some", FOP); }
|
||||
|
||||
#[test]
|
||||
fn long_flag_long_opt_eq_pos() {
|
||||
|
|
|
@ -5,18 +5,32 @@ use clap::{App, Arg};
|
|||
#[test]
|
||||
#[should_panic]
|
||||
fn unique_arg_names() {
|
||||
App::new("some").args(&[Arg::with_name("arg").short("a"), Arg::with_name("arg").short("b")]);
|
||||
let _ = App::new("some")
|
||||
.args(&[
|
||||
Arg::with_name("arg").short("a"),
|
||||
Arg::with_name("arg").short("b"),
|
||||
])
|
||||
.get_matches_safe();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unique_arg_shorts() {
|
||||
App::new("some").args(&[Arg::with_name("arg1").short("a"), Arg::with_name("arg2").short("a")]);
|
||||
let _ = App::new("some")
|
||||
.args(&[
|
||||
Arg::with_name("arg1").short("a"),
|
||||
Arg::with_name("arg2").short("a"),
|
||||
])
|
||||
.get_matches_safe();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unique_arg_longs() {
|
||||
App::new("some")
|
||||
.args(&[Arg::with_name("arg1").long("long"), Arg::with_name("arg2").long("long")]);
|
||||
let _ = App::new("some")
|
||||
.args(&[
|
||||
Arg::with_name("arg1").long("long"),
|
||||
Arg::with_name("arg2").long("long"),
|
||||
])
|
||||
.get_matches_safe();
|
||||
}
|
||||
|
|
143
tests/utf8.rs
143
tests/utf8.rs
|
@ -4,15 +4,14 @@ extern crate clap;
|
|||
|
||||
use std::ffi::OsString;
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
use clap::{App, Arg, AppSettings, ErrorKind};
|
||||
use clap::{App, AppSettings, Arg, ErrorKind};
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_strict_positional() {
|
||||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("<arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -22,9 +21,11 @@ fn invalid_utf8_strict_option_short_space() {
|
|||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -34,8 +35,10 @@ fn invalid_utf8_strict_option_short_equals() {
|
|||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -45,8 +48,10 @@ fn invalid_utf8_strict_option_short_no_space() {
|
|||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
|
||||
]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -56,9 +61,11 @@ fn invalid_utf8_strict_option_long_space() {
|
|||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -68,8 +75,10 @@ fn invalid_utf8_strict_option_long_equals() {
|
|||
let m = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.setting(AppSettings::StrictUtf8)
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(m.is_err());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::InvalidUtf8);
|
||||
}
|
||||
|
@ -78,8 +87,7 @@ fn invalid_utf8_strict_option_long_equals() {
|
|||
fn invalid_utf8_lossy_positional() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("<arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -90,9 +98,11 @@ fn invalid_utf8_lossy_positional() {
|
|||
fn invalid_utf8_lossy_option_short_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -103,8 +113,10 @@ fn invalid_utf8_lossy_option_short_space() {
|
|||
fn invalid_utf8_lossy_option_short_equals() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -115,8 +127,10 @@ fn invalid_utf8_lossy_option_short_equals() {
|
|||
fn invalid_utf8_lossy_option_short_no_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -127,9 +141,11 @@ fn invalid_utf8_lossy_option_short_no_space() {
|
|||
fn invalid_utf8_lossy_option_long_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -140,8 +156,10 @@ fn invalid_utf8_lossy_option_long_space() {
|
|||
fn invalid_utf8_lossy_option_long_equals() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
|
@ -152,72 +170,99 @@ fn invalid_utf8_lossy_option_long_equals() {
|
|||
fn invalid_utf8_positional() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("<arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("-a"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_equals() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_short_no_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_long_space() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from("--arg"),
|
||||
OsString::from_vec(vec![0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_option_long_equals() {
|
||||
let r = App::new("bad_utf8")
|
||||
.arg(Arg::from_usage("-a, --arg <arg> 'some arg'"))
|
||||
.get_matches_from_safe(vec![OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9])]);
|
||||
.get_matches_from_safe(vec![
|
||||
OsString::from(""),
|
||||
OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
|
||||
]);
|
||||
assert!(r.is_ok());
|
||||
let m = r.unwrap();
|
||||
assert!(m.is_present("arg"));
|
||||
assert_eq!(&*m.value_of_os("arg").unwrap(), &*OsString::from_vec(vec![0xe9]));
|
||||
assert_eq!(
|
||||
&*m.value_of_os("arg").unwrap(),
|
||||
&*OsString::from_vec(vec![0xe9])
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ fn complex_version_output() {
|
|||
let mut a = App::new("clap-test").version("v1.4.8");
|
||||
let _ = a.get_matches_from_safe_borrow(vec![""]);
|
||||
|
||||
// Now we check the output of print_version()
|
||||
let mut ver = vec![];
|
||||
a.write_version(&mut ver).unwrap();
|
||||
assert_eq!(str::from_utf8(&ver).unwrap(), VERSION);
|
||||
// Now we check the output of print_version()
|
||||
let mut ver = vec![];
|
||||
a.write_version(&mut ver).unwrap();
|
||||
assert_eq!(str::from_utf8(&ver).unwrap(), VERSION);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![cfg(feature="yaml")]
|
||||
#![cfg(feature = "yaml")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
|
@ -21,8 +21,9 @@ fn help_message() {
|
|||
let mut help_buffer = Vec::new();
|
||||
app.write_help(&mut help_buffer).unwrap();
|
||||
let help_string = String::from_utf8(help_buffer).unwrap();
|
||||
assert!(help_string.contains(
|
||||
"-h, --help prints help with a nonstandard description\n"));
|
||||
assert!(
|
||||
help_string.contains("-h, --help prints help with a nonstandard description\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -35,6 +36,5 @@ fn author() {
|
|||
let mut help_buffer = Vec::new();
|
||||
app.write_help(&mut help_buffer).unwrap();
|
||||
let help_string = String::from_utf8(help_buffer).unwrap();
|
||||
assert!(help_string.contains(
|
||||
"Kevin K. <kbknapp@gmail.com>"));
|
||||
assert!(help_string.contains("Kevin K. <kbknapp@gmail.com>"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue