diff --git a/city-pop/src/main.rs b/city-pop/src/main.rs index c82944e783f5a611bf3cfe9cb800a43f3960c2c7..90278a47e5f0a09e82117825269a04e11ef84076 100644 --- a/city-pop/src/main.rs +++ b/city-pop/src/main.rs @@ -4,8 +4,9 @@ extern crate csv; use getopts::Options; -use std::{env,path,fs}; +use std::{env,fs}; use std::error::Error; +use std::path::Path; // This struct represents the data in each row of the CSV file. // Type based decoding absolves us of a lot of the nitty gritty error @@ -42,10 +43,10 @@ struct PopulationCount { //impl From<String> for Box<Error + Send + Sync> fn print_usage(program: &str, opts: Options) { - println!("{}", opts.usage(&format!("Usage: {} [options] <data-path> <city>",program))); + println!("{}", opts.usage(&format!("Usage: {} [options] <city>",program))); } -fn search<P: AsRef<path::Path>> (file_path: P, city: &str) +fn search<P: AsRef<Path>> (file_path: &Option<P>, city: &str) -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> { let mut found = vec![]; let file = try!(fs::File::open(file_path)); @@ -75,6 +76,7 @@ fn main() { let program = args[0].clone(); let mut opts = Options::new(); + opts.optopt("f","file", "Choose an input file, instead of using STDIN.","NAME"); opts.optflag("h","help","Show this usage message."); let matches = match opts.parse(&args[1..]) { @@ -86,11 +88,17 @@ fn main() { return; } - let data_file = args[1].clone(); - let data_path = path::Path::new(&data_file); - let city = args[2].clone(); + let file = matches.opt_str("f"); + let data_file = file.as_ref().map(Path::new); - for pop in search(&data_path, &city).unwrap() { + let city = if !matches.free.is_empty() { + matches.free[0].clone() + } else { + print_usage(&program, opts); + return; + }; + + for pop in search(&data_file, &city).unwrap() { println!("{}, {}: {:?}",pop.city, pop.country, pop.count); }