From 41fd7bf7a7a548aa3e1da05a3ac8ce2f873249c0 Mon Sep 17 00:00:00 2001 From: Bram Vandenbogaerde Date: Sat, 20 Jul 2019 19:05:58 +0200 Subject: [PATCH] Made wind speed and degree optional by providing a default value + cleaned up the JSON AST traversal code --- src/blocks/weather.rs | 97 +++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/src/blocks/weather.rs b/src/blocks/weather.rs index 2c75067..8236b17 100644 --- a/src/blocks/weather.rs +++ b/src/blocks/weather.rs @@ -48,6 +48,13 @@ pub struct Weather { update_interval: Duration, } +fn malformed_json_error() -> Error { + BlockError( + "weather".to_string(), + "Malformed JSON.".to_string(), + ) +} + impl Weather { fn update_weather(&mut self) -> Result<()> { match self.service { @@ -97,67 +104,41 @@ impl Weather { format!("API Error: {}", val.as_str().unwrap()), )); }; - let raw_weather = match json.pointer("/weather/0/main") + let raw_weather = json.pointer("/weather/0/main") .and_then(|v| v.as_str()) - .map(|s| s.to_string()) { - Some(v) => v, - None => { - return Err(BlockError( - "weather".to_string(), - "Malformed JSON.".to_string(), - )); - } - }; - let raw_temp = match json.pointer("/main/temp").and_then(|v| v.as_f64()) { - Some(v) => v, - None => { - return Err(BlockError( - "weather".to_string(), - "Malformed JSON.".to_string(), - )); - } - }; - let raw_wind_speed = match json.pointer("/wind/speed").and_then(|v| v.as_f64()) { - Some(v) => v, - None => { - return Err(BlockError( - "weather".to_string(), - "Malformed JSON.".to_string(), - )); - } - }; - let raw_wind_direction = match json.pointer("/wind/deg").and_then(|v| v.as_f64()) { - Some(v) => v, - None => { - return Err(BlockError( - "weather".to_string(), - "Malformed JSON.".to_string(), - )); - } - }; - let raw_location = match json.pointer("/name").and_then(|v| v.as_str()).map(|s| { - s.to_string() - }) { - Some(v) => v, - None => { - return Err(BlockError( - "weather".to_string(), - "Malformed JSON.".to_string(), - )); - } - }; + .map(|s| s.to_string()) + .ok_or_else(malformed_json_error)?; + + let raw_temp = json.pointer("/main/temp").and_then(|v| v.as_f64()).ok_or_else(malformed_json_error)?; + + let raw_wind_speed: f64= json.pointer("/wind/speed") + .map_or(Some(0.0), |v| v.as_f64()) // provide default value 0.0 + .ok_or_else(malformed_json_error)?; // error when conversion to f64 fails + + let raw_wind_direction: Option= json.pointer("/wind/deg") + .map_or(Some(None), |v| v.as_f64().and_then(|v| Some(Some(v)))) // provide default value None + .ok_or_else(malformed_json_error)?; // error when conversion to f64 fails + + + let raw_location = json.pointer("/name") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()) + .ok_or_else(malformed_json_error)?; // Convert wind direction in azimuth degrees to abbreviation names - fn convert_wind_direction(direction: f64) -> String { - match direction.round() as i64 { - 24 ... 68 => "NE".to_string(), - 69 ... 113 => "E".to_string(), - 114 ... 158 => "SE".to_string(), - 159 ... 203 => "S".to_string(), - 204 ... 248 => "SW".to_string(), - 249 ... 293 => "W".to_string(), - 294 ... 338 => "NW".to_string(), - _ => "N".to_string() + fn convert_wind_direction(direction_opt: Option) -> String { + match direction_opt { + Some(direction) => match direction.round() as i64 { + 24 ... 68 => "NE".to_string(), + 69 ... 113 => "E".to_string(), + 114 ... 158 => "SE".to_string(), + 159 ... 203 => "S".to_string(), + 204 ... 248 => "SW".to_string(), + 249 ... 293 => "W".to_string(), + 294 ... 338 => "NW".to_string(), + _ => "N".to_string() + }, + None => "-".to_string() } }