diff --git a/city-pop/src/main.rs b/city-pop/src/main.rs index e7a11a969c037e00a796aafeff6258501ec15e9a..6c6dd25a05dbbd729da0dcdea2fcb9323f2612ba 100644 --- a/city-pop/src/main.rs +++ b/city-pop/src/main.rs @@ -1,3 +1,71 @@ +extern crate getopts; +extern crate rustc_serialize; +extern crate csv; + + +use getopts::Options; +use std::{env,path,fs}; + +// 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 +// handling, like parsing strings as integers or floats. +#[derive(Debug,RustcDecodable)] +struct Row { + country: String, + city: String, + accent_city: String, + region: String, + + // Not every row has data for the population, latitude or longitude! + // So we express them as `Option` types, which admits the possibility of + // absence. The CSV parser will fill in the correct value for us. + population: Option<u64>, + latitude: Option<f64>, + longitude: Option<f64>, +} + +struct PopulationCount { + city: String, + country: String + // This is no longer an `Option` because values of this type are only + // constructed if they have a population count. + count: u64, +} + +fn print_usage(program: &str, opts: Options) { + println!("{}", opts.usage(&format!("Usage: {} [options] <data-path> <city>",program))); +} + fn main() { - println!("Hello, world!"); + let args: Vec<String> = env::args().collect(); + let program = args[0].clone(); + + let mut opts = Options::new(); + opts.optflag("h","help","Show this usage message."); + + let matches = match opts.parse(&args[1..]) { + Ok(m) => { m } + Err(e) => { panic!(e.to_string()) } + }; + if matches.opt_present("h") { + print_usage(&program, opts); + return; + } + + let data_file = args[1].clone(); + let data_path = path::Path::new(&data_file); + let city = args[2].clone(); + + let file = fs::File::open(data_path).unwrap(); + let mut rdr = csv::Reader::from_reader(file); + + for row in rdr.decode::<Row>() { + let row = row.unwrap(); + + if row.city == city { + println!("{}, {}: {:?}", + row.city, row.country, + row.population.expect("population count")); + } + } } diff --git a/city-pop/worldcitiespop.csv b/city-pop/worldcitiespop.csv new file mode 100644 index 0000000000000000000000000000000000000000..8924d325b0697f8499d83bba8c33e942f94fead4 Binary files /dev/null and b/city-pop/worldcitiespop.csv differ