mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 22:32:33 +00:00
feat: long flag subcommand infer
Added tests and feature to infer long flag subcommands similarly to normal subcommands.
This commit is contained in:
parent
1ea7178629
commit
ec35ab8813
2 changed files with 91 additions and 2 deletions
|
@ -865,6 +865,41 @@ where
|
|||
None
|
||||
}
|
||||
|
||||
// Checks if the arg matches a long flag subcommand name, or any of it's aliases (if defined)
|
||||
fn possible_long_flag_subcommand(&self, arg_os: &ArgStr<'_>) -> Option<&str> {
|
||||
debug!("Parser::possible_long_flag_subcommand: arg={:?}", arg_os);
|
||||
if self.is_set(AS::InferSubcommands) {
|
||||
let options = self
|
||||
.app
|
||||
.get_subcommands()
|
||||
.iter()
|
||||
.fold(Vec::new(), |mut options, sc| {
|
||||
if let Some(long) = sc.long {
|
||||
if arg_os.is_prefix_of(long) {
|
||||
options.push(long);
|
||||
}
|
||||
options.extend(
|
||||
sc.get_all_aliases()
|
||||
.filter(|alias| arg_os.is_prefix_of(alias)),
|
||||
)
|
||||
}
|
||||
options
|
||||
});
|
||||
if options.len() == 1 {
|
||||
return Some(options[0]);
|
||||
}
|
||||
|
||||
for sc in &options {
|
||||
if sc == arg_os {
|
||||
return Some(sc);
|
||||
}
|
||||
}
|
||||
} else if let Some(sc_name) = self.app.find_long_subcmd(arg_os) {
|
||||
return Some(sc_name);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn parse_help_subcommand(&self, cmds: &[OsString]) -> ClapResult<ParseResult> {
|
||||
debug!("Parser::parse_help_subcommand");
|
||||
|
||||
|
@ -1173,7 +1208,7 @@ where
|
|||
self.parse_flag(opt, matcher)?;
|
||||
|
||||
return Ok(ParseResult::Flag(opt.id.clone()));
|
||||
} else if let Some(sc_name) = self.app.find_long_subcmd(&arg) {
|
||||
} else if let Some(sc_name) = self.possible_long_flag_subcommand(&arg) {
|
||||
return Ok(ParseResult::FlagSubCommand(sc_name.to_string()));
|
||||
} else if self.is_set(AS::AllowLeadingHyphen) {
|
||||
return Ok(ParseResult::MaybeHyphenValue);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use clap::{App, Arg};
|
||||
use clap::{App, AppSettings, Arg, ErrorKind};
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_normal() {
|
||||
|
@ -274,3 +274,57 @@ fn flag_subcommand_conflict_with_version() {
|
|||
.subcommand(App::new("ver").short_flag('V').long_flag("version"))
|
||||
.get_matches_from(vec!["myprog", "--version"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_pass() {
|
||||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(App::new("test").long_flag("test"))
|
||||
.get_matches_from(vec!["prog", "--te"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "suggestions"))]
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_fail() {
|
||||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(App::new("test").long_flag("test"))
|
||||
.subcommand(App::new("temp").long_flag("temp"))
|
||||
.try_get_matches_from(vec!["prog", "--te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[cfg(feature = "suggestions")]
|
||||
#[test]
|
||||
fn flag_subcommand_long_infer_fail() {
|
||||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(App::new("test").long_flag("test"))
|
||||
.subcommand(App::new("temp").long_flag("temp"))
|
||||
.try_get_matches_from(vec!["prog", "--te"]);
|
||||
assert!(m.is_err(), "{:#?}", m.unwrap());
|
||||
assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommands_long_infer_pass_close() {
|
||||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(App::new("test").long_flag("test"))
|
||||
.subcommand(App::new("temp").long_flag("temp"))
|
||||
.get_matches_from(vec!["prog", "--tes"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flag_subcommands_long_infer_exact_match() {
|
||||
let m = App::new("prog")
|
||||
.setting(AppSettings::InferSubcommands)
|
||||
.subcommand(App::new("test").long_flag("test"))
|
||||
.subcommand(App::new("testa").long_flag("testa"))
|
||||
.subcommand(App::new("testb").long_flag("testb"))
|
||||
.get_matches_from(vec!["prog", "--test"]);
|
||||
assert_eq!(m.subcommand_name(), Some("test"));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue