Merge pull request #5051 from joshtriplett/mut-args

Add `Command::mut_args` to modify all arguments of a `Command`
This commit is contained in:
Ed Page 2023-07-31 19:55:03 -05:00 committed by GitHub
commit 56048d8c09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 0 deletions

View file

@ -252,6 +252,52 @@ impl Command {
self
}
/// Allows one to mutate all [`Arg`]s after they've been added to a [`Command`].
///
/// This does not affect the built-in `--help` or `--version` arguments.
///
/// # Examples
///
#[cfg_attr(feature = "string", doc = "```")]
#[cfg_attr(not(feature = "string"), doc = "```ignore")]
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction};
///
/// let mut cmd = Command::new("foo")
/// .arg(Arg::new("bar")
/// .long("bar")
/// .action(ArgAction::SetTrue))
/// .arg(Arg::new("baz")
/// .long("baz")
/// .action(ArgAction::SetTrue))
/// .mut_args(|a| {
/// if let Some(l) = a.get_long().map(|l| format!("prefix-{l}")) {
/// a.long(l)
/// } else {
/// a
/// }
/// });
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "--bar"]);
///
/// // Since we changed `bar`'s long to "prefix-bar" this should err as there
/// // is no `--bar` anymore, only `--prefix-bar`.
///
/// assert!(res.is_err());
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "--prefix-bar"]);
/// assert!(res.is_ok());
/// ```
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_args<F>(mut self, f: F) -> Self
where
F: FnMut(Arg) -> Arg,
{
self.args.mut_args(f);
self
}
/// Allows one to mutate a [`Command`] after it's been added as a subcommand.
///
/// This can be useful for modifying auto-generated arguments of nested subcommands with

View file

@ -123,6 +123,15 @@ impl MKeyMap {
self.args.iter_mut()
}
/// Mutate every argument.
pub(crate) fn mut_args<F>(&mut self, f: F)
where
F: FnMut(Arg) -> Arg,
{
let mut args = std::mem::take(&mut self.args);
self.args.extend(args.drain(..).map(f));
}
/// We need a lazy build here since some we may change args after creating
/// the map, you can checkout who uses `args_mut`.
pub(crate) fn _build(&mut self) {