refactor: adding get_global, making two functions private

preserving the observable behavior of the existing 
public api, while handling global arguments separately in 
get_arg_conflicts_with
This commit is contained in:
hk 2020-11-09 15:29:00 +01:00
parent 5650e37969
commit 895c903b61
3 changed files with 46 additions and 33 deletions

View file

@ -490,9 +490,9 @@ fn arg_conflicts(app: &App, arg: &Arg, app_global: Option<&App>) -> String {
} }
let mut res = vec![]; let mut res = vec![];
match (app_global, App::test_global(arg)) { match (app_global, arg.get_global()) {
(Some(x), true) => { (Some(x), true) => {
let conflicts = x.get_global_arg_conflicts_with(arg); let conflicts = x.get_arg_conflicts_with(arg);
if conflicts.is_empty() { if conflicts.is_empty() {
return String::new(); return String::new();

View file

@ -236,22 +236,20 @@ impl<'help> App<'help> {
self.get_opts().filter(|a| a.get_help_heading().is_none()) self.get_opts().filter(|a| a.get_help_heading().is_none())
} }
/// Test if the provided Argument is a global Argument // Get a list of subcommands which contain the provided Argument
pub fn test_global(arg: &Arg) -> bool { //
arg.global // This command will only include subcommands in its list for which the subcommands
} // parent also contains the Argument.
//
/// Get a list of subcommands which contain the provided Argument // This search follows the propagation rules of global arguments.
/// // It is useful to finding subcommands, that have inherited a global argument.
/// This command will only include subcommands in its list for which the subcommands //
/// parent also contains the Argument. // **NOTE:** In this case only Sucommand_1 will be included
/// // Subcommand_1 (contains Arg)
/// **NOTE:** In this case only Sucommand_1 will be included // Subcommand_1.1 (doesn't contain Arg)
/// Subcommand_1 (contains Arg) // Subcommand_1.1.1 (contains Arg)
/// Subcommand_1.1 (doesn't contain Arg) //
/// Subcommand_1.1.1 (contains Arg) fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> {
///
pub fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> {
let mut vec = std::vec::Vec::new(); let mut vec = std::vec::Vec::new();
for idx in 0..self.subcommands.len() { for idx in 0..self.subcommands.len() {
if self.subcommands[idx] if self.subcommands[idx]
@ -275,13 +273,16 @@ impl<'help> App<'help> {
vec vec
} }
/// Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with. // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with.
/// //
/// ### Panics // This behavior follows the propagation rules of global arguments.
/// // It is useful for finding conflicts for arguments declared as global.
/// If the given arg contains a conflict with an argument that is unknown to //
/// this `App`. // ### Panics
pub fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator //
// If the given arg contains a conflict with an argument that is unknown to
// this `App`.
fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
{ {
arg.blacklist arg.blacklist
.iter() .iter()
@ -305,21 +306,28 @@ impl<'help> App<'help> {
/// Get a list of all arguments the given argument conflicts with. /// Get a list of all arguments the given argument conflicts with.
/// ///
/// If the provided argument is declared as global, the conflicts will be determined
/// based on the propagation rules of global arguments.
///
/// ### Panics /// ### Panics
/// ///
/// If the given arg contains a conflict with an argument that is unknown to /// If the given arg contains a conflict with an argument that is unknown to
/// this `App`. /// this `App`.
pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
{ {
arg.blacklist if arg.global {
.iter() self.get_global_arg_conflicts_with(arg)
.map(|id| { } else {
self.args.args.iter().find(|arg| arg.id == *id).expect( arg.blacklist
"App::get_arg_conflicts_with: \ .iter()
.map(|id| {
self.args.args.iter().find(|arg| arg.id == *id).expect(
"App::get_arg_conflicts_with: \
The passed arg conflicts with an arg unknown to the app", The passed arg conflicts with an arg unknown to the app",
) )
}) })
.collect() .collect()
}
} }
/// Returns `true` if the given [`AppSettings`] variant is currently set in /// Returns `true` if the given [`AppSettings`] variant is currently set in

View file

@ -172,6 +172,11 @@ impl<'help> Arg<'help> {
pub fn get_value_hint(&self) -> ValueHint { pub fn get_value_hint(&self) -> ValueHint {
self.value_hint self.value_hint
} }
/// Get information on if this argument is global or not
pub fn get_global(&self) -> bool {
self.global
}
} }
impl<'help> Arg<'help> { impl<'help> Arg<'help> {