I need to check the second element to determine which action I'm doing to the rest of the arguments.
This loops through the command line arguments and skips the first one because it's always the program name. It also skips the second one because it's the operation I'm performing on the list:
for arg in std::env::args().skip(2)
I am doing the following which is redundant:
let check: Vec<String> = env::args().collect();
if check[1] == 'sort'{
for arg in std::env::args().skip(2){
//sort
}
}
Is there a better way to do this?
You can use nth()
:
let second_arg = env::args().nth(1).expect("no second arg");
which returns an Option<String>
.
It is semantically equivalent to call skip(1)
followed by next()
.
To go further, you can use pattern matching:
let mut args = env::args();
match args.nth(1).as_ref().map(|s| s.as_str()) {
// args has been consumed so it will iterate over the next elements
Some("sort") => for arg in args {
println!("arg: {}", arg);
},
_ => {},
}
It is necessary to convert the argument from String
to &str
in order to be able to use Some("sort")
as-is.
Alternatively, you might want to use a command line parsing package such as clap.
In case you need to check the argument for a flag that may or may not be present, you may be able to use peekable
:
use std::env;
fn main() {
let mut args = env::args()
.skip(1) // skip program name
.peekable(); // allow looking forward one
match args.peek().map(|x| x.as_ref()) {
Some("--option1") => {
args.next(); // Skip the flag
println!("handle option 1");
}
Some("--option2") => {
args.next(); // Skip the flag
println!("handle option 2");
}
_ => {
println!("handle no option");
}
}
}
Realistically, you should use a command line parsing package.