[niepce] rust: use try_opt!() where applicable



commit a8c5d7e41b2d5909810a6868e66eabda0773c219
Author: Hubert Figuière <hub figuiere net>
Date:   Sun Nov 5 18:17:27 2017 -0500

    rust: use try_opt!() where applicable

 Cargo.toml                   |    1 +
 src/engine/db/libmetadata.rs |   11 +---
 src/engine/db/library.rs     |  143 +++++++++++++++++-------------------------
 src/fwk/utils/exempi.rs      |   80 ++++++++---------------
 src/lib.rs                   |    2 +
 5 files changed, 91 insertions(+), 146 deletions(-)
---
diff --git a/Cargo.toml b/Cargo.toml
index 12fa2f4..e7c4feb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,7 @@ gio-sys = "0.4.0"
 gio = "0.2.0"
 libc = "0.2.23"
 rusqlite = { version = "0.12.0", features = ["functions"] }
+try_opt = "0.1.1"
 #gphoto = "0.1.1"
 
 [build-dependencies]
diff --git a/src/engine/db/libmetadata.rs b/src/engine/db/libmetadata.rs
index f6ab6d4..0b33c51 100644
--- a/src/engine/db/libmetadata.rs
+++ b/src/engine/db/libmetadata.rs
@@ -81,11 +81,7 @@ impl LibMetadata {
 
     fn get_metadata(&self, meta: Np) -> Option<PropertyValue> {
 
-        let index_to_xmp = property_index_to_xmp(meta);
-        if index_to_xmp.is_none() {
-            return None;
-        }
-        let index_to_xmp = index_to_xmp.unwrap();
+        let index_to_xmp = try_opt!(property_index_to_xmp(meta));
 
         let mut prop_flags = exempi::PROP_NONE;
         let mut xmp_result = self.xmp.xmp.get_property(&index_to_xmp.ns, &index_to_xmp.property,
@@ -99,10 +95,7 @@ impl LibMetadata {
                 xmp_result = Some(value);
             }
         }
-        if xmp_result.is_some() {
-            return Some(PropertyValue::String(String::from(xmp_result.unwrap().to_str())));
-        }
-        None
+        Some(PropertyValue::String(String::from(try_opt!(xmp_result).to_str())))
     }
 
     pub fn set_metadata(&mut self, meta: Np, value: &PropertyValue) -> bool {
diff --git a/src/engine/db/library.rs b/src/engine/db/library.rs
index 06944ee..4bc0ca2 100644
--- a/src/engine/db/library.rs
+++ b/src/engine/db/library.rs
@@ -83,18 +83,18 @@ impl Library {
 
     fn init(&mut self) -> bool {
         let conn_attempt = rusqlite::Connection::open(self.dbpath.clone());
-        if let Ok(conn) = conn_attempt {
-            let notif_id = self.notif_id;
-            if let Ok(_) = conn.create_scalar_function("rewrite_xmp", 0, false, |_| {
-                Library::notify_by_id(notif_id, Box::new(LibNotification::XmpNeedsUpdate));
-                Ok(true)
-            }) {
-                self.dbconn = Some(conn);
-            } else {
-                err_out!("failed to create scalar functin.");
-                return false;
-            }
+        if !conn_attempt.is_ok() {
+            return false;
+        }
+        let conn = conn_attempt.unwrap();
+        let notif_id = self.notif_id;
+        if let Ok(_) = conn.create_scalar_function("rewrite_xmp", 0, false, |_| {
+            Library::notify_by_id(notif_id, Box::new(LibNotification::XmpNeedsUpdate));
+            Ok(true)
+        }) {
+            self.dbconn = Some(conn);
         } else {
+            err_out!("failed to create scalar functin.");
             return false;
         }
 
@@ -230,13 +230,8 @@ impl Library {
     }
 
     fn leaf_name_for_pathname(pathname: &str) -> Option<String> {
-        let path = Path::new(pathname);
-        if let Some(ref name) = path.file_name() {
-            if let Some(s) = name.to_str() {
-                return Some(String::from(s));
-            }
-        }
-        None
+        let name = try_opt!(Path::new(pathname).file_name());
+        Some(String::from(try_opt!(name.to_str())))
     }
 
     fn get_content(&self, id: LibraryId, sql_where: &str) -> Vec<LibFile> {
@@ -269,41 +264,31 @@ impl Library {
     /// Add folder into parent whose id is `into`.
     /// A value of 0 means root.
     pub fn add_folder_into(&self, folder: &str, into: LibraryId) -> Option<LibFolder> {
-        if let Some(foldername) = Self::leaf_name_for_pathname(folder) {
-            if let Some(ref conn) = self.dbconn {
-                if let Ok(c) = conn.execute(
-                    "INSERT INTO folders (path,name,vault_id,parent_id) VALUES(:1, :2, '0', :3)",
-                    &[&folder, &foldername, &into]) {
-                    if c != 1 {
-                        return None;
-                    }
-                    let id = conn.last_insert_rowid();
-                    dbg_out!("last row inserted {}", id);
-                    let mut lf = LibFolder::new(id, &foldername, &folder);
-                    lf.set_parent(into);
-                    return Some(lf);
-                }
-            }
+        let foldername = try_opt!(Self::leaf_name_for_pathname(folder));
+        let conn = try_opt!(self.dbconn.as_ref());
+        let c = try_opt!(conn.execute(
+            "INSERT INTO folders (path,name,vault_id,parent_id) VALUES(:1, :2, '0', :3)",
+            &[&folder, &foldername, &into]).ok());
+        if c != 1 {
+            return None;
         }
-        None
+        let id = conn.last_insert_rowid();
+        dbg_out!("last row inserted {}", id);
+        let mut lf = LibFolder::new(id, &foldername, &folder);
+        lf.set_parent(into);
+        return Some(lf);
     }
 
     pub fn get_folder(&self, folder: &str) -> Option<LibFolder> {
-        if let Some(foldername) = Self::leaf_name_for_pathname(folder) {
-            if let Some(ref conn) = self.dbconn {
-                let sql = format!("SELECT {} FROM {} WHERE path=:1",
-                                  LibFolder::read_db_columns(),
-                                  LibFolder::read_db_tables());
-                if let Ok(mut stmt) = conn.prepare(&sql) {
-                    let mut rows = stmt.query(&[&foldername]).unwrap();
-                    if let Some(Ok(row)) = rows.next() {
-                        let libfolder = LibFolder::read_from(&row);
-                        return Some(libfolder);
-                    }
-                }
-            }
-        }
-        None
+        let foldername = try_opt!(Self::leaf_name_for_pathname(folder));
+        let conn = try_opt!(self.dbconn.as_ref());
+        let sql = format!("SELECT {} FROM {} WHERE path=:1",
+                          LibFolder::read_db_columns(),
+                          LibFolder::read_db_tables());
+        let mut stmt = try_opt!(conn.prepare(&sql).ok());
+        let mut rows = try_opt!(stmt.query(&[&foldername]).ok());
+        let row = try_opt!(try_opt!(rows.next()).ok());
+        return Some(LibFolder::read_from(&row));
     }
 
     pub fn get_all_folders(&self) -> Vec<LibFolder> {
@@ -375,17 +360,13 @@ impl Library {
     }
 
     fn get_fs_file(&self, id: LibraryId) -> Option<String> {
-        if let Some(ref conn) = self.dbconn {
-            if let Ok(mut stmt) = conn.prepare(
-                "SELECT path FROM fsfiles WHERE id=:1") {
-                let mut rows = stmt.query(&[&id]).unwrap();
-                if let Some(Ok(row)) = rows.next() {
-                    let path : String = row.get(0);
-                    return Some(path);
-                }
-            }
-        }
-        None
+        let conn = try_opt!(self.dbconn.as_ref());
+        let mut stmt = try_opt!(conn.prepare(
+            "SELECT path FROM fsfiles WHERE id=:1").ok());
+        let mut rows = try_opt!(stmt.query(&[&id]).ok());
+        let row = try_opt!(try_opt!(rows.next()).ok());
+        let path : String = row.get(0);
+        return Some(path);
     }
 
     pub fn add_bundle(&self, folder_id: LibraryId, bundle: &FileBundle,
@@ -537,19 +518,14 @@ impl Library {
     }
 
     pub fn get_metadata(&self, file_id: LibraryId) -> Option<LibMetadata> {
-        if let Some(ref conn) = self.dbconn {
-            let sql = format!("SELECT {} FROM {} WHERE id=:1",
-                              LibMetadata::read_db_columns(),
-                              LibMetadata::read_db_tables());
-            if let Ok(mut stmt) = conn.prepare(&sql) {
-                let mut rows = stmt.query(&[&file_id]).unwrap();
-                if let Some(Ok(row)) = rows.next() {
-                    let meta = LibMetadata::read_from(&row);
-                    return Some(meta);
-                }
-            }
-        }
-        None
+        let conn = try_opt!(self.dbconn.as_ref());
+        let sql = format!("SELECT {} FROM {} WHERE id=:1",
+                          LibMetadata::read_db_columns(),
+                          LibMetadata::read_db_tables());
+        let mut stmt = try_opt!(conn.prepare(&sql).ok());
+        let mut rows = try_opt!(stmt.query(&[&file_id]).ok());
+        let row = try_opt!(try_opt!(rows.next()).ok());
+        return Some(LibMetadata::read_from(&row));
     }
 
 
@@ -738,18 +714,15 @@ impl Library {
     }
 
     fn get_xmp_ids_in_queue(&self) -> Option<Vec<LibraryId>> {
-        if let Some(ref conn) = self.dbconn {
-            if let Ok(mut stmt) = conn.prepare("SELECT id FROM xmp_update_queue;") {
-                let mut ids = Vec::<LibraryId>::new();
-                let mut rows = stmt.query(&[]).unwrap();
-                while let Some(Ok(row)) = rows.next() {
-                    let id: i64 = row.get(0);
-                    ids.push(id);
-                }
-                return Some(ids);
-            }
-        }
-        None
+        let conn = try_opt!(self.dbconn.as_ref());
+        let mut stmt = try_opt!(conn.prepare("SELECT id FROM xmp_update_queue;").ok());
+        let mut ids = Vec::<LibraryId>::new();
+        let mut rows = try_opt!(stmt.query(&[]).ok());
+        while let Some(Ok(row)) = rows.next() {
+            let id: i64 = row.get(0);
+            ids.push(id);
+        }
+        return Some(ids);
     }
 
     pub fn write_metadata(&self, id: LibraryId) -> bool {
diff --git a/src/fwk/utils/exempi.rs b/src/fwk/utils/exempi.rs
index 02b1260..4c5326d 100644
--- a/src/fwk/utils/exempi.rs
+++ b/src/fwk/utils/exempi.rs
@@ -212,10 +212,8 @@ impl XmpMeta {
 
     pub fn label(&self) -> Option<String> {
         let mut flags: exempi::PropFlags = exempi::PROP_NONE;
-        if let Some(xmpstring) = self.xmp.get_property(NS_XAP, "Label", &mut flags) {
-            return Some(String::from(xmpstring.to_str()));
-        }
-        None
+        let xmpstring = try_opt!(self.xmp.get_property(NS_XAP, "Label", &mut flags));
+        Some(String::from(xmpstring.to_str()))
     }
 
     pub fn rating(&self) -> Option<i32> {
@@ -230,34 +228,25 @@ impl XmpMeta {
 
     pub fn creation_date(&self) -> Option<DateTime<Utc>> {
         let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
-        if let Some(xmpstring) = self.xmp.get_property(NS_EXIF, "DateTimeOriginal", &mut flags) {
-            if let Ok(date) = DateTime::parse_from_rfc3339(xmpstring.to_str()) {
-                let utc_date = date.with_timezone(&Utc);
-                return Some(utc_date);
-            }
-        }
-        None
+        let xmpstring = try_opt!(self.xmp.get_property(NS_EXIF, "DateTimeOriginal", &mut flags));
+        let date = try_opt!(DateTime::parse_from_rfc3339(xmpstring.to_str()).ok());
+
+        return Some(date.with_timezone(&Utc));
     }
 
     pub fn creation_date_str(&self) -> Option<String> {
         let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
-        if let Some(xmpstring) = self.xmp.get_property(NS_EXIF, "DateTimeOriginal", &mut flags) {
-            return Some(String::from(xmpstring.to_str()));
-        }
-        None
+        let xmpstring = try_opt!(self.xmp.get_property(NS_EXIF, "DateTimeOriginal", &mut flags));
+        Some(String::from(xmpstring.to_str()))
     }
 
     /// Get the date property and return a DateTime<Utc> parsed
     /// from the string value.
     pub fn get_date_property(&self, ns: &str, property: &str) -> Option<DateTime<Utc>> {
         let mut flags: exempi::PropFlags = exempi::PropFlags::empty();
-        if let Some(xmpstring) = self.xmp.get_property(ns, property, &mut flags) {
-            if let Ok(date) = DateTime::parse_from_rfc3339(xmpstring.to_str()) {
-                let utc_date = date.with_timezone(&Utc);
-                return Some(utc_date);
-            }
-        }
-        None
+        let xmpstring = try_opt!(self.xmp.get_property(ns, property, &mut flags));
+        let date = try_opt!(DateTime::parse_from_rfc3339(xmpstring.to_str()).ok());
+        return Some(date.with_timezone(&Utc));
     }
 
     pub fn keywords(&mut self) -> &Vec<String> {
@@ -284,13 +273,11 @@ pub fn gps_coord_from_xmp(xmps: &str) -> Option<f64> {
     let degs: &str;
 
     // step 1 - degrees
-    if let Some(sep) = current.find(',') {
-        let (d, remainder) = current.split_at(sep);
-        current = remainder;
-        degs = d;
-    } else {
-        return None;
-    }
+    let sep = try_opt!(current.find(','));
+    let (d, remainder) = current.split_at(sep);
+    current = remainder;
+    degs = d;
+
     // step 2 - minutes
     if current.len() < 1 {
         return None;
@@ -318,35 +305,24 @@ pub fn gps_coord_from_xmp(xmps: &str) -> Option<f64> {
         let (minutes, seconds) = current.split_at(sep);
         let (_, seconds) = seconds.split_at(1);
         let (seconds, _) = seconds.split_at(seconds.len() - 1);
-        if let Ok(m) = minutes.parse::<f64>() {
-            if let Ok(s) = seconds.parse::<f64>() {
-                fminutes = m + (s / 60f64);
-            } else {
-                return None;
-            }
-        } else {
-            return None;
-        }
+        let m = try_opt!(minutes.parse::<f64>().ok());
+        let s = try_opt!(seconds.parse::<f64>().ok());
+        fminutes = m + (s / 60f64);
     } else {
         // DD,mm.mm format
         let (minutes, _) = current.split_at(current.len() - 1);
-        if let Ok(m) = minutes.parse::<f64>() {
-            fminutes = m;
-        } else {
-            return None;
-        }
+        let m = try_opt!(minutes.parse::<f64>().ok());
+        fminutes = m;
     }
 
-    if let Ok(mut deg) = degs.parse::<f64>() {
-        if deg > 180.0 {
-            return None;
-        }
-        deg += fminutes / 60.0;
-        deg *= orientation;
-
-        return Some(deg);
+    let mut deg = try_opt!(degs.parse::<f64>().ok());
+    if deg > 180.0 {
+        return None;
     }
-    None
+    deg += fminutes / 60.0;
+    deg *= orientation;
+
+    return Some(deg);
 }
 
 #[no_mangle]
diff --git a/src/lib.rs b/src/lib.rs
index 9be6692..7a61001 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -24,6 +24,8 @@ extern crate gio_sys;
 extern crate gio;
 extern crate libc;
 extern crate rusqlite;
+#[macro_use]
+extern crate try_opt;
 
 #[macro_use]
 pub mod fwk;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]