Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Sep 26, 2022
1 parent 18ed37e commit 4094807
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/builder/app_settings.rs
Expand Up @@ -31,6 +31,7 @@ pub(crate) enum AppSettings {
IgnoreErrors,
AllowHyphenValues,
AllowNegativeNumbers,
AllArgsOverrideSelf,
AllowMissingPositional,
TrailingVarArg,
DontDelimitTrailingValues,
Expand Down Expand Up @@ -93,6 +94,7 @@ bitflags! {
const VALID_ARG_FOUND = 1 << 35;
const INFER_SUBCOMMANDS = 1 << 36;
const CONTAINS_LAST = 1 << 37;
const ARGS_OVERRIDE_SELF = 1 << 38;
const HELP_REQUIRED = 1 << 39;
const SUBCOMMAND_PRECEDENCE_OVER_ARG = 1 << 40;
const DISABLE_HELP_FLAG = 1 << 41;
Expand Down Expand Up @@ -163,6 +165,8 @@ impl_settings! { AppSettings, AppFlags,
=> Flags::BIN_NAME_BUILT,
InferSubcommands
=> Flags::INFER_SUBCOMMANDS,
AllArgsOverrideSelf
=> Flags::ARGS_OVERRIDE_SELF,
InferLongArgs
=> Flags::INFER_LONG_ARGS
}
22 changes: 22 additions & 0 deletions src/builder/command.rs
Expand Up @@ -978,6 +978,23 @@ impl Command {
}
}

/// Specifies that all arguments override themselves.
///
/// This is the equivalent to saying the `foo` arg using [`Arg::overrides_with("foo")`] for all
/// defined arguments.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// [`Arg::overrides_with("foo")`]: crate::Arg::overrides_with()
#[inline]
pub fn args_override_self(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::AllArgsOverrideSelf)
} else {
self.unset_global_setting(AppSettings::AllArgsOverrideSelf)
}
}

/// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`]
/// was used.
///
Expand Down Expand Up @@ -3671,6 +3688,11 @@ impl Command {
self.is_set(AppSettings::ArgsNegateSubcommands)
}

#[doc(hidden)]
pub fn is_args_override_self(&self) -> bool {
self.is_set(AppSettings::AllArgsOverrideSelf)
}

/// Report whether [`Command::subcommand_precedence_over_arg`] is set
pub fn is_subcommand_precedence_over_arg_set(&self) -> bool {
self.is_set(AppSettings::SubcommandPrecedenceOverArg)
Expand Down
4 changes: 2 additions & 2 deletions src/parser/arg_matcher.rs
Expand Up @@ -101,8 +101,8 @@ impl ArgMatcher {
self.matches.args.get_mut(arg)
}

pub(crate) fn remove(&mut self, arg: &Id) {
self.matches.args.remove(arg);
pub(crate) fn remove(&mut self, arg: &Id) -> bool {
self.matches.args.remove(arg).is_some()
}

pub(crate) fn contains(&self, arg: &Id) -> bool {
Expand Down
27 changes: 24 additions & 3 deletions src/parser/parser.rs
Expand Up @@ -1179,7 +1179,14 @@ impl<'cmd> Parser<'cmd> {
self.cur_idx.set(self.cur_idx.get() + 1);
debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
}
matcher.remove(&arg.id);
if matcher.remove(&arg.id) && !self.cmd.is_args_override_self() {
return Err(ClapError::argument_conflict(
self.cmd,
arg.to_string(),
vec![arg.to_string()],
Usage::new(self.cmd).create_usage_with_title(&[]),
));
}
self.start_custom_arg(matcher, arg, source);
self.push_arg_values(arg, raw_vals, matcher)?;
if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
Expand Down Expand Up @@ -1213,7 +1220,14 @@ impl<'cmd> Parser<'cmd> {
raw_vals
};

matcher.remove(&arg.id);
if matcher.remove(&arg.id) && !self.cmd.is_args_override_self() {
return Err(ClapError::argument_conflict(
self.cmd,
arg.to_string(),
vec![arg.to_string()],
Usage::new(self.cmd).create_usage_with_title(&[]),
));
}
self.start_custom_arg(matcher, arg, source);
self.push_arg_values(arg, raw_vals, matcher)?;
Ok(ParseResult::ValuesDone)
Expand All @@ -1225,7 +1239,14 @@ impl<'cmd> Parser<'cmd> {
raw_vals
};

matcher.remove(&arg.id);
if matcher.remove(&arg.id) && self.cmd.is_args_conflicts_with_self() {
return Err(ClapError::argument_conflict(
self.cmd,
arg.to_string(),
vec![arg.to_string()],
Usage::new(self.cmd).create_usage_with_title(&[]),
));
}
self.start_custom_arg(matcher, arg, source);
self.push_arg_values(arg, raw_vals, matcher)?;
Ok(ParseResult::ValuesDone)
Expand Down

0 comments on commit 4094807

Please sign in to comment.