Skip to content
Snippets Groups Projects
Commit ea039162 authored by Administrator's avatar Administrator
Browse files

Finished with city_pop

parent bc0527e3
No related branches found
No related tags found
No related merge requests found
......@@ -4,10 +4,50 @@ extern crate csv;
use getopts::Options;
use std::{env,fs,io};
use std::{env,fmt,fs,io,process};
use std::error::Error;
use std::path::Path;
#[derive(Debug)]
enum CliError {
Io(io::Error),
Csv(csv::Error),
NotFound,
}
impl fmt::Display for CliError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
CliError::Io(ref err) => err.fmt(f),
CliError::Csv(ref err) => err.fmt(f),
CliError::NotFound => write!(f,"No matching cities with a population were found."),
}
}
}
impl Error for CliError {
fn description(&self) -> &str {
match *self {
CliError::Io(ref err) => err.description(),
CliError::Csv(ref err) => err.description(),
CliError::NotFound => "not found",
}
}
}
impl From<io::Error> for CliError {
fn from(err: io::Error) -> CliError {
CliError::Io(err)
}
}
impl From<csv::Error> for CliError {
fn from(err: csv::Error) -> CliError {
CliError::Csv(err)
}
}
// 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.
......@@ -47,7 +87,7 @@ fn print_usage(program: &str, opts: Options) {
}
fn search<P: AsRef<Path>> (file_path: &Option<P>, city: &str)
-> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
-> Result<Vec<PopulationCount>, CliError> {
let mut found = vec![];
let input: Box<io::Read> = match *file_path {
None => Box::new(io::stdin()),
......@@ -68,7 +108,7 @@ fn search<P: AsRef<Path>> (file_path: &Option<P>, city: &str)
}
}
if found.is_empty() {
Err(From::from("No matching cities with a population were found."))
Err(CliError::NotFound)
} else {
Ok(found)
}
......@@ -81,6 +121,7 @@ fn main() {
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.");
opts.optflag("q","quit","Silences errors and warnings.");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
......@@ -101,8 +142,12 @@ fn main() {
return;
};
for pop in search(&data_file, &city).unwrap() {
match search(&data_file, &city) {
Err(CliError::NotFound) if matches.opt_present("q") => process::exit(1),
Err(err) => panic!("{}", err),
Ok(pops) => for pop in pops {
println!("{}, {}: {:?}",pop.city, pop.country, pop.count);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment