0
votes

I've been reading the Rust doc, and I finished chapter 13. I updated the minigrep program to use iterators in the Config struct. Now I am trying to re-implement the command line argument using iterators.

What I am trying to do is parse command-line arguments using iterators. Project code:

    pub fn new(mut args: env::Args) -> Result<Config, &'static str> {
        args.next();
        
        let query = match args.next() {
            Some(arg) => arg,
            None => return Err("No query string"),
        };
        
        let filename = match args.next() {
            Some(arg) => arg,
            None => return Err("No Filename"),
        };
        // --snip--
    }

I need to compare the first iterator with the optional command-line argument "-c" without consuming the iterator in case the argument is not there.

The first thing I tried was args.eq([String::from("-c")].iter());

But got the error no implementation for `String == &String

Next I tried to use args.copied().collect(); got the error expected struct `String`, found reference Bug?

Then I tried args.map(|x: &String| x).collect(); and got expected signature of `fn(String) -> _` Bug?

I tried other methods as well such as: by_ref, peekable, and cloned

My question is:

How can I compare the first iterator item of an env::Args to a string without consuming the iterator?

1

1 Answers

2
votes

How can I compare the first iterator item of an env::Args to a string without consuming the iterator?

You probably want to use Iterator::peekable, which wraps your original iterator into an iterator that offers a method peek. That method returns a reference to the next item without advancing (or consuming) the iterator!

let mut it = args.peekable();
if it.peek().map(|s| s.as_str()) == Some("-a") {
    
}

Since it.peek() returns Option<&String>, I also mapped it to s.as_str() to be able to compare it easily to Some("-a"), without allocating a String for "-a".