diff --git a/clap_builder/src/parser/parser.rs b/clap_builder/src/parser/parser.rs index a00ed02a158..fcde4a86e4b 100644 --- a/clap_builder/src/parser/parser.rs +++ b/clap_builder/src/parser/parser.rs @@ -573,28 +573,29 @@ impl<'cmd> Parser<'cmd> { fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> { debug!("Parser::possible_long_flag_subcommand: arg={arg:?}"); if self.cmd.is_infer_subcommands_set() { - let options = self - .cmd - .get_subcommands() - .fold(Vec::new(), |mut options, sc| { - if let Some(long) = sc.get_long_flag() { - if long.starts_with(arg) { - options.push(long); - } - options.extend(sc.get_all_aliases().filter(|alias| alias.starts_with(arg))) + let mut iter = self.cmd.get_subcommands().filter_map(|sc| { + sc.get_long_flag().and_then(|long| { + if long.starts_with(arg) { + Some(sc.get_name()) + } else { + sc.get_all_long_flag_aliases().find_map(|alias| { + if alias.starts_with(arg) { + Some(sc.get_name()) + } else { + None + } + }) } - options - }); - if options.len() == 1 { - return Some(options[0]); - } + }) + }); - for sc in options { - if sc == arg { - return Some(sc); + if let name @ Some(_) = iter.next() { + if iter.next().is_none() { + return name; } } - } else if let Some(sc_name) = self.cmd.find_long_subcmd(arg) { + } + if let Some(sc_name) = self.cmd.find_long_subcmd(arg) { return Some(sc_name); } None diff --git a/tests/builder/app_settings.rs b/tests/builder/app_settings.rs index 1fa3d919ecb..151e9d31774 100644 --- a/tests/builder/app_settings.rs +++ b/tests/builder/app_settings.rs @@ -264,7 +264,6 @@ fn infer_subcommands_pass_conflicting_aliases() { } #[test] -#[should_panic(expected = "internal error")] fn infer_long_flag_pass_conflicting_aliases() { let m = Command::new("prog") .infer_subcommands(true) @@ -273,12 +272,12 @@ fn infer_long_flag_pass_conflicting_aliases() { .long_flag("test") .long_flag_aliases(["testa", "t", "testb"]), ) - .try_get_matches_from(vec!["prog", "--te"]); - assert!(m.is_err(), "{:#?}", m.unwrap()); + .try_get_matches_from(vec!["prog", "--te"]) + .unwrap(); + assert_eq!(m.subcommand_name(), Some("c")); } #[test] -#[should_panic(expected = "internal error")] fn infer_long_flag() { let m = Command::new("prog") .infer_subcommands(true)