From 7e4cd4362070eb7b5463485e8c258f8e03f3c3be Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 4 Jan 2022 12:48:04 -0600 Subject: [PATCH] feat(parser): Allow users to avoid undefined arg asserts Cargo is an example of a user that heavily relied on using undefined names because there is a lot of code sharing between commands. This allows a path forward for those users that is just painful enough to discourage overly relying on it in the future :). --- src/parse/matches/arg_matches.rs | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/parse/matches/arg_matches.rs b/src/parse/matches/arg_matches.rs index 33e69352..619bf5df 100644 --- a/src/parse/matches/arg_matches.rs +++ b/src/parse/matches/arg_matches.rs @@ -993,6 +993,44 @@ impl ArgMatches { pub fn subcommand_name(&self) -> Option<&str> { self.subcommand.as_ref().map(|sc| &*sc.name) } + + /// Check if an arg can be queried + /// + /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer + /// mistakes. In some context, this doesn't work, so users can use this function to check + /// before they do a query on `ArgMatches`. + #[inline] + #[doc(hidden)] + pub fn is_valid_arg(&self, _id: impl Key) -> bool { + #[cfg(debug_assertions)] + { + let id = Id::from(_id); + id == Id::empty_hash() || self.valid_args.contains(&id) + } + #[cfg(not(debug_assertions))] + { + true + } + } + + /// Check if a subcommand can be queried + /// + /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer + /// mistakes. In some context, this doesn't work, so users can use this function to check + /// before they do a query on `ArgMatches`. + #[inline] + #[doc(hidden)] + pub fn is_valid_subcommand(&self, _id: impl Key) -> bool { + #[cfg(debug_assertions)] + { + let id = Id::from(_id); + id == Id::empty_hash() || self.valid_subcommands.contains(&id) + } + #[cfg(not(debug_assertions))] + { + true + } + } } // Private methods