Skip to content

Commit

Permalink
feat(Indices): implements an Indices<Item=&usize> iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
kbknapp committed Mar 3, 2018
1 parent c4c414e commit 1e67be4
Showing 1 changed file with 66 additions and 1 deletion.
67 changes: 66 additions & 1 deletion src/args/arg_matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,10 +821,62 @@ impl<'a> Default for OsValues<'a> {
}
}

/// An iterator for getting multiple indices out of an argument via the [`ArgMatches::indices_of`]
/// method.
///
/// # Examples
///
/// ```rust
/// # use clap::{App, Arg};
/// let m = App::new("myapp")
/// .arg(Arg::with_name("output")
/// .short("o")
/// .multiple(true)
/// .takes_value(true))
/// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
///
/// let indices = m.indices_of("output").unwrap();
///
/// assert_eq!(indicies.next(), Some(2));
/// assert_eq!(indicies.next(), Some(3));
/// assert_eq!(indicies.next(), None);
/// ```
/// [`ArgMatches::indices_of`]: ./struct.ArgMatches.html#method.indices_of
#[derive(Clone)]
#[allow(missing_debug_implementations)]
pub struct Indices<'a> {
iter: Map<Iter<'a, OsString>, fn(&'a OsString) -> &'a usize>,
}

impl<'a> Iterator for Indices<'a> {
type Item = &'a usize;

fn next(&mut self) -> Option<&'a str> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl<'a> DoubleEndedIterator for Indices<'a> {
fn next_back(&mut self) -> Option<&'a usize> { self.iter.next_back() }
}

impl<'a> ExactSizeIterator for Indices<'a> {}

/// Creates an empty iterator.
impl<'a> Default for Indices<'a> {
fn default() -> Self {
static EMPTY: [usize; 0] = [];
// This is never called because the iterator is empty:
fn to_usize_ref(_: &OsString) -> &usize { unreachable!() };
Indices {
iter: EMPTY[..].iter().map(to_usize_ref),
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_default_values() {
let mut values: Values = Values::default();
Expand All @@ -850,4 +902,17 @@ mod tests {
let mut values = matches.values_of_os("").unwrap_or_default();
assert_eq!(values.next(), None);
}

#[test]
fn test_default_indices() {
let mut indices: Indices = Indices::default();
assert_eq!(indices.next(), None);
}

#[test]
fn test_default_indices_with_shorter_lifetime() {
let matches = ArgMatches::new();
let mut indices = matches.indices_of("").unwrap_or_default();
assert_eq!(indices.next(), None);
}
}

0 comments on commit 1e67be4

Please sign in to comment.