From 04e6450d40547c5bf421d4b00e6848e1234d345e Mon Sep 17 00:00:00 2001
From: Anders Nilsson <anders.nilsson@control.lth.se>
Date: Mon, 30 Nov 2015 16:36:56 +0100
Subject: [PATCH] More error handling

---
 city-pop/src/main.rs | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/city-pop/src/main.rs b/city-pop/src/main.rs
index 7737fce..c82944e 100644
--- a/city-pop/src/main.rs
+++ b/city-pop/src/main.rs
@@ -5,6 +5,7 @@ extern crate csv;
 
 use getopts::Options;
 use std::{env,path,fs};
+use std::error::Error;
 
 // 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
@@ -32,13 +33,22 @@ struct PopulationCount {
     count: u64,
 }
 
+// We are making use of this impl in the code above, since we call `From::from`
+// on a `&'static str`.
+//impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a>
+
+// But this is also useful when you need to allocate a new string for an
+// error message, usually with `format!`.
+//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)));
 }
 
-fn search<P: AsRef<path::Path>>(file_path: P, city: &str) -> Vec<PopulationCount> {
+fn search<P: AsRef<path::Path>> (file_path: P, city: &str)
+                                 -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
     let mut found = vec![];
-    let file = fs::File::open(file_path).unwrap();
+    let file = try!(fs::File::open(file_path));
     let mut rdr = csv::Reader::from_reader(file);
     for row in rdr.decode::<Row>() {
         let row = row.unwrap();
@@ -53,7 +63,11 @@ fn search<P: AsRef<path::Path>>(file_path: P, city: &str) -> Vec<PopulationCount
             },
         }
     }
-    found
+    if found.is_empty() {
+        Err(From::from("No matching cities with a population were found."))
+    } else {
+        Ok(found)
+    }
 }
 
 fn main() {
@@ -76,7 +90,7 @@ fn main() {
     let data_path = path::Path::new(&data_file);
     let city = args[2].clone();
 
-    for pop in search(&data_path, &city) {
+    for pop in search(&data_path, &city).unwrap() {
         println!("{}, {}: {:?}",pop.city, pop.country, pop.count);
     }
 
-- 
GitLab