From 1e2ac14d3b0176d538b03c9be17b536b9bcee4c1 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 4 Jan 2018 23:09:30 +0100 Subject: [PATCH] Refactoring: Use function chaining rather than matching --- lib/entry/libimagentrygps/src/entry.rs | 7 ++-- lib/entry/libimagentrygps/src/types.rs | 44 +++++++++++--------------- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/lib/entry/libimagentrygps/src/entry.rs b/lib/entry/libimagentrygps/src/entry.rs index 5a7c2df2..641fefde 100644 --- a/lib/entry/libimagentrygps/src/entry.rs +++ b/lib/entry/libimagentrygps/src/entry.rs @@ -64,10 +64,9 @@ impl GPSEntry for Entry { } fn get_coordinates(&self) -> Result> { - match self.get_header().read("gps.coordinates").chain_err(|| GPSEK::HeaderWriteError) { - Ok(Some(hdr)) => Coordinates::from_value(hdr).map(Some), - Ok(None) => Ok(None), - Err(e) => Err(e), + match self.get_header().read("gps.coordinates").chain_err(|| GPSEK::HeaderWriteError)? { + Some(hdr) => Coordinates::from_value(hdr).map(Some), + None => Ok(None), } } diff --git a/lib/entry/libimagentrygps/src/types.rs b/lib/entry/libimagentrygps/src/types.rs index 2b70de19..569013e9 100644 --- a/lib/entry/libimagentrygps/src/types.rs +++ b/lib/entry/libimagentrygps/src/types.rs @@ -78,31 +78,27 @@ impl Into for GPSValue { impl FromValue for GPSValue { fn from_value(v: &Value) -> Result { + let int_to_appropriate_width = |v: &Value| { + v.as_integer() + .ok_or(GPSE::from_kind(GPSEK::HeaderTypeError)).and_then(i64_to_i8) + }; + match *v { Value::Table(ref map) => { Ok(GPSValue::new( map.get("degree") .ok_or_else(|| GPSE::from_kind(GPSEK::DegreeMissing)) - .and_then(|v| match *v { - Value::Integer(i) => i64_to_i8(i), - _ => Err(GPSE::from_kind(GPSEK::HeaderTypeError)), - })?, + .and_then(&int_to_appropriate_width)?, map .get("minutes") .ok_or_else(|| GPSE::from_kind(GPSEK::MinutesMissing)) - .and_then(|v| match *v { - Value::Integer(i) => i64_to_i8(i), - _ => Err(GPSE::from_kind(GPSEK::HeaderTypeError)), - })?, + .and_then(&int_to_appropriate_width)?, map .get("seconds") .ok_or_else(|| GPSE::from_kind(GPSEK::SecondsMissing)) - .and_then(|v| match *v { - Value::Integer(i) => i64_to_i8(i), - _ => Err(GPSE::from_kind(GPSEK::HeaderTypeError)), - })? + .and_then(&int_to_appropriate_width)? )) } _ => Err(GPSE::from_kind(GPSEK::TypeError)) @@ -154,22 +150,18 @@ impl Into for Coordinates { impl FromValue for Coordinates { fn from_value(v: &Value) -> Result { - match *v { - Value::Table(ref map) => { - Ok(Coordinates::new( - match map.get("longitude") { - Some(v) => GPSValue::from_value(v), - None => Err(GPSE::from_kind(GPSEK::LongitudeMissing)), - }?, + v.as_table() + .ok_or(GPSE::from_kind(GPSEK::TypeError)) + .and_then(|t| { + let get = |m: &BTreeMap<_, _>, what: &'static str, ek| -> Result { + m.get(what).ok_or(GPSE::from_kind(ek)).and_then(GPSValue::from_value) + }; - match map.get("latitude") { - Some(v) => GPSValue::from_value(v), - None => Err(GPSE::from_kind(GPSEK::LongitudeMissing)), - }? + Ok(Coordinates::new( + get(t, "longitude", GPSEK::LongitudeMissing)?, + get(t, "latitude", GPSEK::LatitudeMissing)? )) - } - _ => Err(GPSE::from_kind(GPSEK::TypeError)) - } + }) } }