fix: Generalize mut_arg, like mut_subcommand

This makes us accept `str` and not do any allocations at the cost of
panicing if unsupported which I think fits our overall story in trying
to catch development-time errors.
This commit is contained in:
Ed Page 2022-09-16 11:54:02 -05:00
parent dbf2c86995
commit acb0fb7809
3 changed files with 17 additions and 11 deletions

View file

@ -239,6 +239,7 @@ Easier to catch changes:
- *(assert)* Ensure `overrides_with` IDs are valid
- *(assert)* Ensure no self-`overrides_with` now that Actions replace it
- *(assert)* Ensure subcommand names are not duplicated
- *(assert)* Assert on `mut_arg` receiving an invalid arg ID or `mut_subcommand` receiving an invalid command name
### Compatibility

View file

@ -205,6 +205,10 @@ impl Command {
///
/// This can be useful for modifying the auto-generated help or version arguments.
///
/// # Panics
///
/// If the argument is undefined
///
/// # Examples
///
/// ```rust
@ -227,15 +231,16 @@ impl Command {
/// assert!(res.is_ok());
/// ```
#[must_use]
pub fn mut_arg<F>(mut self, arg_id: impl Into<Id>, f: F) -> Self
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_arg<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(Arg) -> Arg,
{
let id = arg_id.into();
let id = arg_id.as_ref();
let a = self
.args
.remove_by_name(id.as_str())
.unwrap_or_else(|| Arg::new(id));
.remove_by_name(id)
.unwrap_or_else(|| panic!("Argument `{}` is undefined", id));
self.args.push(f(a));
self
@ -246,6 +251,10 @@ impl Command {
/// This can be useful for modifying auto-generated arguments of nested subcommands with
/// [`Command::mut_arg`].
///
/// # Panics
///
/// If the subcommand is undefined
///
/// # Examples
///
/// ```rust
@ -275,7 +284,7 @@ impl Command {
let subcmd = if let Some(idx) = pos {
self.subcommands.remove(idx)
} else {
Self::new(Str::from(name.to_owned()))
panic!("Command `{}` is undefined", name)
};
self.subcommands.push(f(subcmd));

View file

@ -291,13 +291,9 @@ fn version_required() {
}
#[test]
#[should_panic = "Argument `version` is undefined"]
fn mut_arg_version_no_auto_version() {
let res = common()
.mut_arg("version", |v| v.short('z').action(ArgAction::SetTrue))
.try_get_matches_from("foo -z".split(' '));
assert!(res.is_ok(), "{}", res.unwrap_err());
assert_eq!(res.unwrap().get_one::<bool>("version").copied(), Some(true));
let _ = common().mut_arg("version", |v| v.short('z').action(ArgAction::SetTrue));
}
#[cfg(debug_assertions)]