Dear rust users,
I'm trying to teach myself rust by writing a useful but small program with it. The program needs to do something with a Vec<&str>
. I've managed to write some code as shown at the end of the post. This compiles, but I had to repeat do_something_with_vec(v);
twice which is bothering me. Ideally I'd like to call it once like the below.
let v: Vec<&str>;
if matches.is_present("list") {
// get 'v' from the command line: --list foo,bar,baz
v = matches.value_of("list").unwrap().split(",").collect();
} else {
let r = get_vec_from_file(matches.value_of("file").unwrap());
v = r.iter().map(|s| s.as_ref()).collect(); // error: borrowed value does not live long enough
}
do_something_with_vec(v);
I'd be very grateful if someone gave me a steer on what the correct approach in Rust is.
extern crate clap;
use clap::{App, Arg};
use std::fs;
fn main() {
let matches = App::new("A test program")
.arg(
Arg::with_name("list")
.short("l")
.long("list")
.help("comma-delimited list of items")
.conflicts_with("file")
.required_unless("file")
.takes_value(true),
)
.arg(
Arg::with_name("file")
.short("f")
.long("file")
.required_unless("list")
.help("file containing items, one per line")
.takes_value(true),
)
.get_matches();
let v: Vec<&str>;
if matches.is_present("list") {
// get 'v' from the command line: --list foo,bar,baz
v = matches.value_of("list").unwrap().split(",").collect();
do_something_with_vec(v);
} else {
let r = get_vec_from_file(matches.value_of("file").unwrap());
v = r.iter().map(|s| s.as_ref()).collect();
do_something_with_vec(v);
// this compiles but I had to repeat "do_something_with_list(v);" twice -- is
// there a better way?
}
}
fn get_vec_from_file(filename: &str) -> Vec<String> {
let contents = fs::read_to_string(filename).expect("could not open file");
let mut file_lines: Vec<String> = Vec::new();
contents
.lines()
.for_each(|line| file_lines.push(String::from(line)));
file_lines
}
fn do_something_with_vec(v: Vec<&str>) {
for item in v {
println!("{}", item);
}
}