[niepce] commands: display errors from library



commit 0e3585476169f1cd85d9bcbc6ef227d975292afd
Author: Hubert Figuière <hub figuiere net>
Date:   Wed Oct 10 13:14:40 2018 -0400

    commands: display errors from library
    
    - Added err_out_line!() macro to display file and lineno

 src/engine/db/library.rs       |   2 +-
 src/engine/library/commands.rs | 364 +++++++++++++++++++++++++++--------------
 src/fwk/base/debug.rs          |  16 +-
 3 files changed, 254 insertions(+), 128 deletions(-)
---
diff --git a/src/engine/db/library.rs b/src/engine/db/library.rs
index 6169234..136fbad 100644
--- a/src/engine/db/library.rs
+++ b/src/engine/db/library.rs
@@ -66,7 +66,7 @@ impl From<rusqlite::Error> for Error {
     }
 }
 
-type Result<T> = result::Result<T, Error>;
+pub type Result<T> = result::Result<T, Error>;
 
 pub struct Library {
     // maindir: PathBuf,
diff --git a/src/engine/library/commands.rs b/src/engine/library/commands.rs
index 61d7fd7..ae53601 100644
--- a/src/engine/library/commands.rs
+++ b/src/engine/library/commands.rs
@@ -22,6 +22,7 @@ use std::path::Path;
 
 use fwk::PropertyValue;
 use engine::db::LibraryId;
+use engine::db::library;
 use engine::db::library::{
     Library,
     Managed
@@ -40,41 +41,67 @@ use super::notification::{
 use root::eng::NiepceProperties as Np;
 
 pub fn cmd_list_all_keywords(lib: &Library) -> bool {
-    if let Ok(list) = lib.get_all_keywords() {
-        // XXX change this to "LoadKeywords"
-        for kw in list {
-            lib.notify(Box::new(LibNotification::AddedKeyword(kw)));
+    match  lib.get_all_keywords() {
+        Ok(list) => {
+            // XXX change this to "LoadKeywords"
+            for kw in list {
+                lib.notify(Box::new(LibNotification::AddedKeyword(kw)));
+            }
+            true
+        },
+        Err(err) => {
+            err_out_line!("get all keywords failed: {:?}", err);
+            false
         }
-        return true;
     }
-    false
 }
 
 pub fn cmd_list_all_folders(lib: &Library) -> bool {
-    if let Ok(list) = lib.get_all_folders() {
-        // XXX change this to "LoadedFolders"
-        for folder in list {
-            lib.notify(Box::new(LibNotification::AddedFolder(folder)));
+    match lib.get_all_folders() {
+        Ok(list) => {
+            // XXX change this to "LoadedFolders"
+            for folder in list {
+                lib.notify(Box::new(LibNotification::AddedFolder(folder)));
+            }
+            true
+        },
+        Err(err) => {
+            err_out_line!("get_all_folders failed: {:?}", err);
+            false
         }
-        return true;
     }
-    false
 }
 
 //
 // Get the folder for import. Create it if needed otherwise return the one that exists
 //
-fn get_folder_for_import(lib: &Library, folder: &str) -> Option<LibFolder> {
-    if let Ok(lf) = lib.get_folder(folder) {
-        return Some(lf);
-    } else if let Some(name) = Library::leaf_name_for_pathname(folder) {
-        if let Ok(lf) = lib.add_folder(&name, Some(String::from(folder))) {
-            let libfolder = lf.clone();
-            lib.notify(Box::new(LibNotification::AddedFolder(lf)));
-            return Some(libfolder);
+fn get_folder_for_import(lib: &Library, folder: &str) -> library::Result<LibFolder> {
+    match lib.get_folder(folder) {
+        Ok(lf) => Ok(lf),
+        Err(library::Error::NotFound) => {
+            // folder doesn't exist, we'll create it
+            if let Some(name) = Library::leaf_name_for_pathname(folder) {
+                match lib.add_folder(&name, Some(String::from(folder))) {
+                    Ok(lf) =>  {
+                        let libfolder = lf.clone();
+                        lib.notify(Box::new(LibNotification::AddedFolder(lf)));
+                        Ok(libfolder)
+                    },
+                    Err(err) => {
+                        err_out_line!("Add folder failed {:?}", err);
+                        Err(err)
+                    }
+                }
+            } else {
+                err_out_line!("Can't get folder name.");
+                Err(library::Error::InvalidResult)
+            }
+        },
+        Err(err) => {
+            err_out_line!("get folder failed: {:?}", err);
+            Err(err)
         }
     }
-    None
 }
 
 pub fn cmd_import_file(lib: &Library, path: &str, manage: Managed) -> bool {
@@ -85,13 +112,24 @@ pub fn cmd_import_file(lib: &Library, path: &str, manage: Managed) -> bool {
 
     let folder = Path::new(path).parent().unwrap_or(Path::new(""));
 
-    if let Some(libfolder) = get_folder_for_import(lib, &*folder.to_string_lossy()) {
-        if let Ok(_) = lib.add_bundle(libfolder.id(), &bundle, manage) {
-            lib.notify(Box::new(LibNotification::AddedFile));
-            return true;
+    match get_folder_for_import(lib, &*folder.to_string_lossy()) {
+        Ok(libfolder) =>  {
+            match lib.add_bundle(libfolder.id(), &bundle, manage) {
+                Ok(_) =>  {
+                    lib.notify(Box::new(LibNotification::AddedFile));
+                    true
+                },
+                Err(err) => {
+                    err_out_line!("Failed to add bundle {:?}", err);
+                    false
+                }
+            }
+        },
+        Err(err) => {
+            err_out_line!("Can't get folder name for import: {:?}.", err);
+            false
         }
     }
-    false
 }
 
 pub fn cmd_import_files(lib: &Library, folder: &str, files: &Vec<String>,
@@ -99,176 +137,250 @@ pub fn cmd_import_files(lib: &Library, folder: &str, files: &Vec<String>,
     dbg_assert!(manage == Managed::NO, "managing file is currently unsupported");
 
     let bundles = FileBundle::filter_bundles(files);
-    if let Some(libfolder) = get_folder_for_import(lib, folder) {
-        let folder_id = libfolder.id();
-        for bundle in bundles {
-            if let Err(err) = lib.add_bundle(folder_id, &bundle, manage.clone()) {
-                err_out!("Add bundle failed: {:?}", err);
+    match get_folder_for_import(lib, folder) {
+        Ok(libfolder) =>  {
+            let folder_id = libfolder.id();
+            for bundle in bundles {
+                if let Err(err) = lib.add_bundle(folder_id, &bundle, manage.clone()) {
+                    err_out!("Add bundle failed: {:?}", err);
+                }
             }
+            lib.notify(Box::new(LibNotification::AddedFiles));
+            true
+        },
+        Err(err) => {
+            err_out_line!("Get folder for import {:?}", err);
+            false
         }
-        lib.notify(Box::new(LibNotification::AddedFiles));
-        return true;
     }
-    false
 }
 
 pub fn cmd_create_folder(lib: &Library, name: &String, path: Option<String>) -> LibraryId {
-    if let Ok(lf) = lib.add_folder(name, path) {
-        let id = lf.id();
-        lib.notify(Box::new(LibNotification::AddedFolder(lf)));
-        return id;
+    match lib.add_folder(name, path) {
+        Ok(lf) =>  {
+            let id = lf.id();
+            lib.notify(Box::new(LibNotification::AddedFolder(lf)));
+            id
+        },
+        Err(err) =>  {
+            err_out_line!("Folder creation failed {:?}", err);
+            -1
+        }
     }
-    -1
 }
 
 pub fn cmd_delete_folder(lib: &Library, id: LibraryId) -> bool {
-    if lib.delete_folder(id).is_ok() {
-        lib.notify(Box::new(LibNotification::FolderDeleted(id)));
-        return true;
+    match lib.delete_folder(id) {
+        Ok(_) => {
+            lib.notify(Box::new(LibNotification::FolderDeleted(id)));
+            true
+        },
+        Err(err) => {
+            err_out_line!("Delete folder failed {:?}", err);
+            false
+        }
     }
-    false
 }
 
 pub fn cmd_request_metadata(lib: &Library, file_id: LibraryId) -> bool {
-    if let Ok(lm) = lib.get_metadata(file_id) {
-        lib.notify(Box::new(LibNotification::MetadataQueried(lm)));
-        return true;
+    match lib.get_metadata(file_id) {
+        Ok(lm) => {
+            lib.notify(Box::new(LibNotification::MetadataQueried(lm)));
+            true
+        },
+        Err(err) => {
+            err_out_line!("Get metadata failed {:?}", err);
+            false
+        }
     }
-    false
 }
 
 pub fn cmd_query_folder_content(lib: &Library, folder_id: LibraryId) -> bool {
-    if let Ok(fl) = lib.get_folder_content(folder_id) {
-        let mut value = Box::new(
-            LibNotification::FolderContentQueried(unsafe { Content::new(folder_id) }));
-        if let LibNotification::FolderContentQueried(ref mut content) = *value {
-            for f in fl {
-                unsafe { content.push(Box::into_raw(Box::new(f)) as *mut c_void) };
+    match lib.get_folder_content(folder_id) {
+        Ok(fl) => {
+            let mut value = Box::new(
+                LibNotification::FolderContentQueried(unsafe { Content::new(folder_id) }));
+            if let LibNotification::FolderContentQueried(ref mut content) = *value {
+                for f in fl {
+                    unsafe { content.push(Box::into_raw(Box::new(f)) as *mut c_void) };
+                }
             }
+            lib.notify(value);
+            true
+        },
+        Err(err) => {
+            err_out_line!("Get folder content failed {:?}", err);
+            false
         }
-        lib.notify(value);
-        return true;
     }
-    false
 }
 
 pub fn cmd_set_metadata(lib: &Library, id: LibraryId, meta: Np,
                         value: &PropertyValue) -> bool {
-    let err = lib.set_metadata(id, meta, value);
-    if err.is_ok() {
-        lib.notify(Box::new(LibNotification::MetadataChanged(
-            MetadataChange::new(id, meta as u32, Box::new(value.clone())))));
-        true
-    } else {
-        err_out!("set_matadata failed: {:?}", err);
-        false
+    match lib.set_metadata(id, meta, value) {
+        Ok(_) => {
+            lib.notify(Box::new(LibNotification::MetadataChanged(
+                MetadataChange::new(id, meta as u32, Box::new(value.clone())))));
+            true
+        },
+        Err(err) => {
+            err_out_line!("set_matadata failed: {:?}", err);
+            false
+        }
     }
 }
 
 pub fn cmd_count_folder(lib: &Library, folder_id: LibraryId) -> bool {
-    let err = lib.count_folder(folder_id);
-    if let Ok(count) = err {
-        lib.notify(Box::new(LibNotification::FolderCounted(
-            Count{id: folder_id, count: count})));
-        true
-    } else {
-        err_out!("count_folder failed: {:?}", err);
-        false
+    match lib.count_folder(folder_id) {
+        Ok(count) => {
+            lib.notify(Box::new(LibNotification::FolderCounted(
+                Count{id: folder_id, count: count})));
+            true
+        },
+        Err(err) => {
+            err_out_line!("count_folder failed: {:?}", err);
+            false
+        }
     }
 }
 
 pub fn cmd_add_keyword(lib: &Library, keyword: &str) -> LibraryId {
-    let err = lib.make_keyword(keyword);
-    if let Ok(id) = err {
-        lib.notify(Box::new(LibNotification::AddedKeyword(Keyword::new(id, keyword))));
-        id
-    } else {
-        err_out!("add_keyword failed: {:?}", err);
-        -1
+    match lib.make_keyword(keyword) {
+        Ok(id) => {
+            lib.notify(Box::new(LibNotification::AddedKeyword(Keyword::new(id, keyword))));
+            id
+        },
+        Err(err) => {
+            err_out_line!("make_keyword failed: {:?}", err);
+            -1
+        }
     }
 }
 
 pub fn cmd_query_keyword_content(lib: &Library, keyword_id: LibraryId) -> bool {
-    if let Ok(fl) = lib.get_keyword_content(keyword_id) {
-        let mut content = unsafe { Content::new(keyword_id) };
-        for f in fl {
-            unsafe { content.push(Box::into_raw(Box::new(f)) as *mut c_void) };
+    match lib.get_keyword_content(keyword_id) {
+        Ok(fl) => {
+            let mut content = unsafe { Content::new(keyword_id) };
+            for f in fl {
+                unsafe { content.push(Box::into_raw(Box::new(f)) as *mut c_void) };
+            }
+            lib.notify(Box::new(LibNotification::KeywordContentQueried(content)));
+            true
+        },
+        Err(err) => {
+            err_out_line!("get_keyword_content failed: {:?}", err);
+            false
         }
-        lib.notify(Box::new(LibNotification::KeywordContentQueried(content)));
-        return true;
     }
-    false
 }
 
 pub fn cmd_count_keyword(lib: &Library, id: LibraryId) -> bool {
-    if let Ok(count) = lib.count_keyword(id) {
-        lib.notify(Box::new(LibNotification::KeywordCounted(
-            Count{id: id, count: count})));
-        return true;
+    match lib.count_keyword(id) {
+        Ok(count) => {
+            lib.notify(Box::new(LibNotification::KeywordCounted(
+                Count{id: id, count: count})));
+            true
+        },
+        Err(err) => {
+            err_out_line!("count_keyword failed: {:?}", err);
+            false
+        }
     }
-    false
 }
 
 pub fn cmd_write_metadata(lib: &Library, file_id: LibraryId) -> bool {
-    lib.write_metadata(file_id).is_ok()
+    match lib.write_metadata(file_id) {
+        Ok(_) => true,
+        Err(err) => {
+            err_out_line!("write_metadata failed: {:?}", err);
+            false
+        }
+    }
 }
 
 pub fn cmd_move_file_to_folder(lib: &Library, file_id: LibraryId, from: LibraryId,
                                to: LibraryId) -> bool {
-
-    if lib.move_file_to_folder(file_id, to).is_ok() {
-        lib.notify(Box::new(LibNotification::FileMoved(
-            FileMove{file: file_id, from: from, to: to})));
-        lib.notify(Box::new(LibNotification::FolderCountChanged(
-            Count{id: from, count: -1})));
-        lib.notify(Box::new(LibNotification::FolderCountChanged(
-            Count{id: to, count: 1})));
-        return true;
+    match lib.move_file_to_folder(file_id, to) {
+        Ok(_) => {
+            lib.notify(Box::new(LibNotification::FileMoved(
+                FileMove{file: file_id, from: from, to: to})));
+            lib.notify(Box::new(LibNotification::FolderCountChanged(
+                Count{id: from, count: -1})));
+            lib.notify(Box::new(LibNotification::FolderCountChanged(
+                Count{id: to, count: 1})));
+            true
+        },
+        Err(err) => {
+            err_out_line!("move file to folder failed: {:?}", err);
+            false
+        }
     }
-    false
 }
 
 pub fn cmd_list_all_labels(lib: &Library) -> bool {
-    if let Ok(l) = lib.get_all_labels() {
-        // XXX change this notification type
-        for label in l {
-            lib.notify(Box::new(LibNotification::AddedLabel(label)));
+    match lib.get_all_labels() {
+        Ok(l) => {
+            // XXX change this notification type
+            for label in l {
+                lib.notify(Box::new(LibNotification::AddedLabel(label)));
+            }
+            true
+        },
+        Err(err) => {
+            err_out_line!("get_all_labels failed: {:?}", err);
+            false
         }
-        return true;
     }
-    false
 }
 
 pub fn cmd_create_label(lib: &Library, name: &str, colour: &str) -> LibraryId {
-    if let Ok(id) = lib.add_label(name, colour) {
-        let l = Label::new(id, name, colour);
-        lib.notify(Box::new(LibNotification::AddedLabel(l)));
-        id
-    } else {
-        -1
+    match lib.add_label(name, colour) {
+        Ok(id) => {
+            let l = Label::new(id, name, colour);
+            lib.notify(Box::new(LibNotification::AddedLabel(l)));
+            id
+        },
+        Err(err) => {
+            err_out_line!("add_label failed: {:?}", err);
+            -1
+        }
     }
 }
 
 pub fn cmd_delete_label(lib: &Library, label_id: LibraryId) -> bool {
-    if let Ok(_) = lib.delete_label(label_id) {
-        lib.notify(Box::new(LibNotification::LabelDeleted(label_id)));
-        true
-    } else {
-        false
+    match lib.delete_label(label_id) {
+        Ok(_) => {
+            lib.notify(Box::new(LibNotification::LabelDeleted(label_id)));
+            true
+        },
+        Err(err) => {
+            err_out_line!("delete label failed: {:?}", err);
+            false
+        }
     }
 }
 
 pub fn cmd_update_label(lib: &Library, label_id: LibraryId, name: &str,
                         colour: &str) -> bool {
-    if let Ok(_) = lib.update_label(label_id, name, colour) {
-        let label = Label::new(label_id, name, colour);
-        lib.notify(Box::new(LibNotification::LabelChanged(label)));
-        true
-    } else {
-        false
+    match lib.update_label(label_id, name, colour) {
+        Ok(_) => {
+            let label = Label::new(label_id, name, colour);
+            lib.notify(Box::new(LibNotification::LabelChanged(label)));
+            true
+        },
+        Err(err) => {
+            err_out_line!("update label failed: {:?}", err);
+            false
+        }
     }
 }
 
 pub fn cmd_process_xmp_update_queue(lib: &Library, write_xmp: bool) -> bool {
-    lib.process_xmp_update_queue(write_xmp).is_ok()
+    match lib.process_xmp_update_queue(write_xmp) {
+        Ok(_) => true,
+        Err(err) => {
+            err_out_line!("process_xmp_update_queue failed: {:?}", err);
+            false
+        }
+    }
 }
diff --git a/src/fwk/base/debug.rs b/src/fwk/base/debug.rs
index 5e3fc22..7970ba6 100644
--- a/src/fwk/base/debug.rs
+++ b/src/fwk/base/debug.rs
@@ -7,6 +7,7 @@ macro_rules! dbg_out {
     };
 }
 
+/// Print an error message on the console.
 #[macro_export]
 macro_rules! err_out {
     ( $( $x:expr ),* ) => {
@@ -17,12 +18,25 @@ macro_rules! err_out {
     };
 }
 
+/// Like err_out!() but print the file and line number
+#[macro_export]
+macro_rules! err_out_line {
+    ( $( $x:expr ),* ) => {
+        {
+            print!("ERROR: {}:{}:", file!(), line!());
+            println!( $($x),* );
+        }
+    };
+}
+
+/// Assert and print a message if true.
+/// Does NOT abort of call assert!()
 #[macro_export]
 macro_rules! dbg_assert {
     ( $cond:expr,  $msg:expr ) => {
         {
             if !$cond {
-                print!("ASSERT: {}", stringify!($cond));
+                print!("ASSERT: {}:{}: {}", file!(), line!(), stringify!($cond));
                 println!( $msg );
             }
         }


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