From b7fa72d40f18806ec2042dd67a518401c2cf5681 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Sun, 29 Mar 2015 17:08:23 -0400 Subject: [PATCH] feat(positionals): add assertions for positional args with multiple vals --- src/app.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/app.rs b/src/app.rs index c2a991e4..e6dd5621 100644 --- a/src/app.rs +++ b/src/app.rs @@ -207,6 +207,9 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{ if a.short.is_some() || a.long.is_some() { panic!("Argument \"{}\" has conflicting requirements, both index() and short(), or long(), were supplied", a.name); } + if self.positionals_idx.contains_key(&i) { + panic!("Argument \"{}\" has the same index as another positional argument", a.name); + } // if a.multiple { // panic!("Argument \"{}\" has conflicting requirements, both index() and multiple(true) were supplied",a.name); // } @@ -555,6 +558,11 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{ } pub fn get_matches(mut self) -> ArgMatches<'ar> { + self.verify_positionals(); + for sc in self.subcommands.values() { + sc.verify_positionals(); + } + let mut matches = ArgMatches::new(); let args = env::args().collect::>(); @@ -572,6 +580,29 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{ matches } + fn verify_positionals(&self) { + // Because you must wait until all arguments have been supplied, this is the first chance + // to make assertions on positional argument indexes + // + // Firt we verify that the index highest supplied index, is equal to the number of + // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3 + // but no 2) + // + // Next we verify that only the highest index has a .multiple(true) (if any) + if let Some((idx, ref p)) = self.positionals_idx.iter().rev().next() { + if *idx as usize != self.positionals_idx.len() { + panic!("Found positional argument \"{}\" who's index is {} but there are only {} positional arguments defined", p.name, idx, self.positionals_idx.len()); + } + } + if let Some(ref p) = self.positionals_idx.values() + .filter(|ref a| a.multiple) + .filter(|ref a| a.index as usize != self.positionals_idx.len()) + .next() { + panic!("Found positional argument \"{}\" which accepts multiple values but it's not the last positional argument (i.e. others have a higher index)", + p.name); + } + } + fn get_matches_from(&mut self, matches: &mut ArgMatches<'ar>, it: &mut IntoIter) { self.create_help_and_version();