diff --git a/clap_builder/src/builder/command.rs b/clap_builder/src/builder/command.rs index b2efdbc7..48ee1a9e 100644 --- a/clap_builder/src/builder/command.rs +++ b/clap_builder/src/builder/command.rs @@ -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(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 diff --git a/clap_builder/src/mkeymap.rs b/clap_builder/src/mkeymap.rs index e9d6ab84..301c7bc5 100644 --- a/clap_builder/src/mkeymap.rs +++ b/clap_builder/src/mkeymap.rs @@ -123,6 +123,15 @@ impl MKeyMap { self.args.iter_mut() } + /// Mutate every argument. + pub(crate) fn mut_args(&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) {