Skip to content

Commit 94003db

Browse files
committed
feat: adds abiltiy not consume self when parsing matches and/or exit on help
1 parent f9144c9 commit 94003db

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

src/app/app.rs

+42-11
Original file line numberDiff line numberDiff line change
@@ -1924,8 +1924,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
19241924
matches
19251925
}
19261926

1927-
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
1928-
/// the real parsing function for all subcommands
1927+
/// Starts the parsing process without consuming the `App` struct `self`. This is normally not
1928+
/// the desired functionality, instead prefer `App::get_matches_from_safe` which *does*
1929+
/// consume `self`.
19291930
///
19301931
/// **NOTE:** The first argument will be parsed as the binary name.
19311932
///
@@ -1936,21 +1937,20 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
19361937
/// **NOTE:** This method should only be used when is absolutely necessary to handle errors
19371938
/// manually.
19381939
///
1939-
///
19401940
/// # Example
19411941
///
19421942
/// ```no_run
19431943
/// # use clap::{App, Arg};
19441944
/// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
19451945
///
1946-
/// let matches = App::new("myprog")
1946+
/// let mut app = App::new("myprog");
19471947
/// // Args and options go here...
1948-
/// .get_matches_from_safe(arg_vec)
1948+
/// let matches = app.get_matches_from_safe_borrow(arg_vec)
19491949
/// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) });
19501950
/// ```
1951-
pub fn get_matches_from_safe<I, T>(mut self,
1952-
itr: I)
1953-
-> Result<ArgMatches<'ar, 'ar>, ClapError>
1951+
pub fn get_matches_from_safe_borrow<I, T>(&mut self,
1952+
itr: I)
1953+
-> Result<ArgMatches<'ar, 'ar>, ClapError>
19541954
where I: IntoIterator<Item = T>,
19551955
T: AsRef<str>
19561956
{
@@ -1987,6 +1987,39 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
19871987
Ok(matches)
19881988
}
19891989

1990+
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
1991+
/// the real parsing function for all subcommands
1992+
///
1993+
/// **NOTE:** The first argument will be parsed as the binary name.
1994+
///
1995+
/// **NOTE:** This method should only be used when absolutely necessary, such as needing to
1996+
/// parse arguments from something other than `std::env::args()`. If you are unsure, use
1997+
/// `App::get_matches_safe()`
1998+
///
1999+
/// **NOTE:** This method should only be used when is absolutely necessary to handle errors
2000+
/// manually.
2001+
///
2002+
///
2003+
/// # Example
2004+
///
2005+
/// ```no_run
2006+
/// # use clap::{App, Arg};
2007+
/// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2008+
///
2009+
/// let matches = App::new("myprog")
2010+
/// // Args and options go here...
2011+
/// .get_matches_from_safe(arg_vec)
2012+
/// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) });
2013+
/// ```
2014+
pub fn get_matches_from_safe<I, T>(mut self,
2015+
itr: I)
2016+
-> Result<ArgMatches<'ar, 'ar>, ClapError>
2017+
where I: IntoIterator<Item = T>,
2018+
T: AsRef<str>
2019+
{
2020+
self.get_matches_from_safe_borrow(itr)
2021+
}
2022+
19902023
fn verify_positionals(&mut self) {
19912024
// Because you must wait until all arguments have been supplied, this is the first chance
19922025
// to make assertions on positional argument indexes
@@ -2251,7 +2284,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
22512284
// may be trying to pass might match a subcommand name
22522285
if !pos_only {
22532286
if self.subcommands.contains_key(arg_slice) {
2254-
if arg_slice == "help" {
2287+
if arg_slice == "help" && self.needs_subcmd_help {
22552288
self.print_help();
22562289
}
22572290
subcmd_name = Some(arg_slice.to_owned());
@@ -2343,7 +2376,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
23432376
vals.insert(len, arg_slice.to_owned());
23442377
}
23452378
}
2346-
23472379
} else {
23482380
// Only increment the positional counter if it doesn't allow multiples
23492381
pos_counter += 1;
@@ -2407,7 +2439,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
24072439

24082440
parse_group_reqs!(self, p);
24092441
}
2410-
24112442
} else {
24122443
return Err(self.report_error(format!("The argument '{}' was found, but '{}' \
24132444
wasn't expecting any", Format::Warning(arg.as_ref()),

0 commit comments

Comments
 (0)