mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 06:42:33 +00:00
Marry AllowExternalSubcommands with SubcommandRequiredElse*
This commit is contained in:
parent
ee463ba834
commit
6bdb6d9b2e
7 changed files with 57 additions and 41 deletions
|
@ -162,7 +162,6 @@ fn test_tuple_commands() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn external_subcommand() {
|
||||
#[derive(Debug, PartialEq, Clap)]
|
||||
struct Opt {
|
||||
|
@ -172,25 +171,25 @@ fn external_subcommand() {
|
|||
|
||||
#[derive(Debug, PartialEq, Clap)]
|
||||
enum Subcommands {
|
||||
// Add,
|
||||
// Remove,
|
||||
Add,
|
||||
Remove,
|
||||
#[clap(external_subcommand)]
|
||||
Other(Vec<String>),
|
||||
}
|
||||
|
||||
// assert_eq!(
|
||||
// Opt::parse_from(&["test", "add"]),
|
||||
// Opt {
|
||||
// sub: Subcommands::Add
|
||||
// }
|
||||
// );
|
||||
assert_eq!(
|
||||
Opt::parse_from(&["test", "add"]),
|
||||
Opt {
|
||||
sub: Subcommands::Add
|
||||
}
|
||||
);
|
||||
|
||||
// assert_eq!(
|
||||
// Opt::parse_from(&["test", "remove"]),
|
||||
// Opt {
|
||||
// sub: Subcommands::Remove
|
||||
// }
|
||||
// );
|
||||
assert_eq!(
|
||||
Opt::parse_from(&["test", "remove"]),
|
||||
Opt {
|
||||
sub: Subcommands::Remove
|
||||
}
|
||||
);
|
||||
|
||||
assert!(Opt::try_parse_from(&["test"]).is_err());
|
||||
|
||||
|
@ -203,7 +202,6 @@ fn external_subcommand() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn external_subcommand_os_string() {
|
||||
use std::ffi::OsString;
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/external_subcommand_wrong_type.rs:13:15
|
||||
|
|
||||
13 | Other(Vec<CString>),
|
||||
| ^^^^^^^ expected struct `std::ffi::CString`, found struct `std::ffi::OsString`
|
||||
|
|
||||
= note: expected struct `std::vec::Vec<std::ffi::CString>`
|
||||
found struct `std::vec::Vec<std::ffi::OsString>`
|
5
clap_derive/tests/ui/multiple_external_subcommand.stderr
Normal file
5
clap_derive/tests/ui/multiple_external_subcommand.stderr
Normal file
|
@ -0,0 +1,5 @@
|
|||
error: Only one variant can be marked with `external_subcommand`, this is the second
|
||||
--> $DIR/multiple_external_subcommand.rs:14:12
|
||||
|
|
||||
14 | #[clap(external_subcommand)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
|
@ -1,4 +1,4 @@
|
|||
error: subcommand, flatten and skip cannot be used together
|
||||
error: `subcommand`, `flatten`, `external_subcommand` and `skip` cannot be used together
|
||||
--> $DIR/skip_flatten.rs:17:18
|
||||
|
|
||||
17 | #[clap(skip, flatten)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: subcommand, flatten and skip cannot be used together
|
||||
error: `subcommand`, `flatten`, `external_subcommand` and `skip` cannot be used together
|
||||
--> $DIR/skip_subcommand.rs:17:24
|
||||
|
|
||||
17 | #[clap(subcommand, skip)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: subcommand, flatten and skip cannot be used together
|
||||
error: `subcommand`, `flatten`, `external_subcommand` and `skip` cannot be used together
|
||||
--> $DIR/subcommand_and_flatten.rs:16:24
|
||||
|
|
||||
16 | #[clap(subcommand, flatten)]
|
||||
|
|
|
@ -381,6 +381,7 @@ where
|
|||
let has_args = self.has_args();
|
||||
|
||||
let mut subcmd_name: Option<String> = None;
|
||||
let mut external_subcommand = false;
|
||||
let mut needs_val_of: ParseResult = ParseResult::NotFound;
|
||||
let mut pos_counter = 1;
|
||||
let mut replace: Option<&[&str]> = None;
|
||||
|
@ -677,6 +678,8 @@ where
|
|||
matches: sc_m.into_inner(),
|
||||
});
|
||||
|
||||
external_subcommand = true;
|
||||
|
||||
break;
|
||||
} else if !((self.is_set(AS::AllowLeadingHyphen)
|
||||
|| self.is_set(AS::AllowNegativeNumbers))
|
||||
|
@ -718,28 +721,30 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(ref pos_sc_name) = subcmd_name {
|
||||
let sc_name = find_subcmd!(self.app, *pos_sc_name)
|
||||
.expect(INTERNAL_ERROR_MSG)
|
||||
.name
|
||||
.clone();
|
||||
self.parse_subcommand(&sc_name, matcher, it)?;
|
||||
} else if self.is_set(AS::SubcommandRequired) {
|
||||
let bn = self.app.bin_name.as_ref().unwrap_or(&self.app.name);
|
||||
return Err(ClapError::missing_subcommand(
|
||||
bn,
|
||||
&Usage::new(self).create_usage_with_title(&[]),
|
||||
self.app.color(),
|
||||
)?);
|
||||
} else if self.is_set(AS::SubcommandRequiredElseHelp) {
|
||||
debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
|
||||
let message = self.write_help_err()?;
|
||||
return Err(ClapError {
|
||||
cause: String::new(),
|
||||
message,
|
||||
kind: ErrorKind::MissingArgumentOrSubcommand,
|
||||
info: None,
|
||||
});
|
||||
if !external_subcommand {
|
||||
if let Some(ref pos_sc_name) = subcmd_name {
|
||||
let sc_name = find_subcmd!(self.app, *pos_sc_name)
|
||||
.expect(INTERNAL_ERROR_MSG)
|
||||
.name
|
||||
.clone();
|
||||
self.parse_subcommand(&sc_name, matcher, it)?;
|
||||
} else if self.is_set(AS::SubcommandRequired) {
|
||||
let bn = self.app.bin_name.as_ref().unwrap_or(&self.app.name);
|
||||
return Err(ClapError::missing_subcommand(
|
||||
bn,
|
||||
&Usage::new(self).create_usage_with_title(&[]),
|
||||
self.app.color(),
|
||||
)?);
|
||||
} else if self.is_set(AS::SubcommandRequiredElseHelp) {
|
||||
debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
|
||||
let message = self.write_help_err()?;
|
||||
return Err(ClapError {
|
||||
cause: String::new(),
|
||||
message,
|
||||
kind: ErrorKind::MissingArgumentOrSubcommand,
|
||||
info: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.remove_overrides(matcher);
|
||||
|
|
Loading…
Reference in a new issue