Stewart
Stewart

Reputation: 4992

Rust String vs &str iterators

I'm trying to write a function which accepts a list of tokens. But I'm having problems making it general enough to handle two pretty similar calls:

let s = String::from("-abc -d --echo");

parse( s.split_ascii_whitespace() );
parse( std::env::args() );

Is there a way for me to write a function signature for parse that will accept both methods?

My solution right now requires duplicating function bodies:

fn main() {
    let s = String::from("-abc -d --echo");

    parse_args( s.split_ascii_whitespace() );
    parse_env( std::env::args() );
}

fn parse_env<I: Iterator<Item=String>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s),
        }
    }
}

fn parse_args<'a, I: Iterator<Item=&'a str>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s),
        }
    }
}

If not possible, then some advice on how to use the traits so the functions can use the same name would be nice.

Upvotes: 7

Views: 1169

Answers (2)

Sven Marnach
Sven Marnach

Reputation: 601539

You can require the item type to be AsRef<str>, which will include both &str and String:

fn parse<I>(mut it: I)
where
    I: Iterator,
    I::Item: AsRef<str>,
{
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}", s.as_ref()),
        }
    }
}

Upvotes: 10

phimuemue
phimuemue

Reputation: 35983

Depending on your use case, you could try:

fn main() {
    let s = String::from("-abc -d --echo");

    parse( s.split_ascii_whitespace() );
    parse( std::env::args() );
}

fn parse<T: std::borrow::Borrow<str>, I: Iterator<Item=T>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s.borrow()),
        }
    }
}

I used Borrow as a means to get to a &str, but your concrete use case may be served by other, possibly custom, traits.

Upvotes: 1

Related Questions