From f1f7abddae6d250f61a18ddb210f59bf72b6214b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 25 Oct 2019 17:20:56 +0200 Subject: [PATCH 1/7] Add iterator extensions for store-id touched reporting Signed-off-by: Matthias Beyer --- lib/core/libimagrt/src/iter.rs | 139 +++++++++++++++++++++++++++++++++ lib/core/libimagrt/src/lib.rs | 1 + 2 files changed, 140 insertions(+) create mode 100644 lib/core/libimagrt/src/iter.rs diff --git a/lib/core/libimagrt/src/iter.rs b/lib/core/libimagrt/src/iter.rs new file mode 100644 index 00000000..282570ad --- /dev/null +++ b/lib/core/libimagrt/src/iter.rs @@ -0,0 +1,139 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2019 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +/// Iterator extension helpers for `Runtime::report_touched` +mod reporting { + use std::ops::Deref; + + use libimagstore::store::Entry; + use libimagstore::storeid::StoreId; + use failure::Fallible as Result; + use failure::Error; + + use runtime::Runtime; + + + pub trait ReportTouchedEntry<'a, I, D> + where I: Iterator, + D: Deref, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedEntryImpl<'a, I, D>; + } + + impl<'a, I, D> ReportTouchedEntry<'a, I, D> for I + where I: Iterator, + D: Deref, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedEntryImpl<'a, I, D> { + ReportTouchedEntryImpl(self, rt) + } + } + + pub struct ReportTouchedEntryImpl<'a, I, D>(I, &'a Runtime<'a>) + where I: Iterator, + D: Deref; + + impl<'a, I, D> Iterator for ReportTouchedEntryImpl<'a, I, D> + where I: Iterator, + D: Deref, + { + type Item = Result; + + fn next(&mut self) -> Option { + self.0.next().map(|e| self.1.report_touched(e.get_location()).map_err(Error::from).map(|_| e)) + } + } + + + + + pub trait ReportTouchedStoreId<'a, I> + where I: Iterator + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedStoreIdImpl<'a, I>; + } + + impl<'a, I> ReportTouchedStoreId<'a, I> for I + where I: Iterator, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedStoreIdImpl<'a, I> { + ReportTouchedStoreIdImpl(self, rt) + } + } + + pub struct ReportTouchedStoreIdImpl<'a, I>(I, &'a Runtime<'a>) + where I: Iterator; + + impl<'a, I> Iterator for ReportTouchedStoreIdImpl<'a, I> + where I: Iterator, + { + type Item = Result; + + fn next(&mut self) -> Option { + self.0 + .next() + .map(|id| { + self.1 + .report_touched(&id) + .map_err(Error::from) + .map(|_| id) + }) + } + } + + + + pub trait ReportTouchedResultStoreId<'a, I> + where I: Iterator> + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedResultStoreIdImpl<'a, I>; + } + + impl<'a, I> ReportTouchedResultStoreId<'a, I> for I + where I: Iterator>, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedResultStoreIdImpl<'a, I> { + ReportTouchedResultStoreIdImpl(self, rt) + } + } + + pub struct ReportTouchedResultStoreIdImpl<'a, I>(I, &'a Runtime<'a>) + where I: Iterator>; + + impl<'a, I> Iterator for ReportTouchedResultStoreIdImpl<'a, I> + where I: Iterator>, + { + type Item = Result; + + fn next(&mut self) -> Option { + self.0 + .next() + .map(|rid| { + rid.and_then(|id| { + self.1 + .report_touched(&id) + .map_err(Error::from) + .map(|_| id) + }) + }) + } + } +} + +pub use self::reporting::*; diff --git a/lib/core/libimagrt/src/lib.rs b/lib/core/libimagrt/src/lib.rs index f9d349c0..afa5534f 100644 --- a/lib/core/libimagrt/src/lib.rs +++ b/lib/core/libimagrt/src/lib.rs @@ -59,6 +59,7 @@ pub mod application; pub mod configuration; pub mod logger; pub mod io; +pub mod iter; pub mod runtime; pub mod setup; pub mod spec; From 0095dda99657f522d7bdbaaf25bc8ade79f3b0db Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:23:00 +0200 Subject: [PATCH 2/7] Add extension trait for iterator over Result Signed-off-by: Matthias Beyer --- lib/core/libimagrt/src/iter.rs | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lib/core/libimagrt/src/iter.rs b/lib/core/libimagrt/src/iter.rs index 282570ad..c0d179c9 100644 --- a/lib/core/libimagrt/src/iter.rs +++ b/lib/core/libimagrt/src/iter.rs @@ -61,6 +61,46 @@ mod reporting { } + pub trait ReportTouchedResultEntry<'a, I, D> + where I: Iterator>, + D: Deref, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedResultEntryImpl<'a, I, D>; + } + + impl<'a, I, D> ReportTouchedResultEntry<'a, I, D> for I + where I: Iterator>, + D: Deref, + { + fn map_report_touched(self, rt: &'a Runtime) -> ReportTouchedResultEntryImpl<'a, I, D> { + ReportTouchedResultEntryImpl(self, rt) + } + } + + pub struct ReportTouchedResultEntryImpl<'a, I, D>(I, &'a Runtime<'a>) + where I: Iterator>, + D: Deref; + + impl<'a, I, D> Iterator for ReportTouchedResultEntryImpl<'a, I, D> + where I: Iterator>, + D: Deref, + { + type Item = Result; + + fn next(&mut self) -> Option { + self.0.next() + .map(|r| { + r.and_then(|e| { + self.1 + .report_touched(e.get_location()) + .map_err(Error::from) + .map(|_| e) + }) + }) + } + } + + pub trait ReportTouchedStoreId<'a, I> From a6effe7ef388a3224572204f6d821f96856acc03 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:30:38 +0200 Subject: [PATCH 3/7] Add id reporting in imag-annotate Signed-off-by: Matthias Beyer --- bin/core/imag-annotate/Cargo.toml | 1 + bin/core/imag-annotate/src/lib.rs | 32 +++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/bin/core/imag-annotate/Cargo.toml b/bin/core/imag-annotate/Cargo.toml index 63cdc07c..5c5b89da 100644 --- a/bin/core/imag-annotate/Cargo.toml +++ b/bin/core/imag-annotate/Cargo.toml @@ -25,6 +25,7 @@ url = "2" toml = "0.5.1" toml-query = "0.9.2" failure = "0.1.5" +resiter = "0.4.0" libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-annotate/src/lib.rs b/bin/core/imag-annotate/src/lib.rs index 0e80fbe5..61ce94ae 100644 --- a/bin/core/imag-annotate/src/lib.rs +++ b/bin/core/imag-annotate/src/lib.rs @@ -40,6 +40,7 @@ extern crate log; #[macro_use] extern crate failure; extern crate toml_query; +extern crate resiter; extern crate libimagentryannotation; extern crate libimagentryedit; @@ -55,6 +56,9 @@ use failure::Error; use failure::Fallible as Result; use failure::ResultExt; use failure::err_msg; +use resiter::IterInnerOkOrElse; +use resiter::AndThen; +use resiter::Map; use toml_query::read::TomlValueReadTypeExt; use clap::App; @@ -67,6 +71,7 @@ use libimagrt::application::ImagApplication; use libimagstore::store::FileLockEntry; use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagentrylink::linkable::Linkable; +use libimagrt::iter::ReportTouchedResultEntry; mod ui; @@ -121,12 +126,13 @@ fn add(rt: &Runtime) -> Result<()> { annotation.edit_content(&rt)?; - for id in ids { - let mut entry = rt.store().get(id.clone())? - .ok_or_else(|| format_err!("Not found: {}", id.local_display_string()))?; - - entry.add_link(&mut annotation)?; - } + rt.report_touched(&first)?; // report first one first + ids.map(Ok).into_get_iter(rt.store()) + .map_inner_ok_or_else(|| err_msg("Did not find one entry")) + .and_then_ok(|mut entry| entry.add_link(&mut annotation).map(|_| entry)) + .map_report_touched(&rt) + .map_ok(|_| ()) + .collect::>>()?; if !scmd.is_present("dont-print-name") { if let Some(annotation_id) = annotation @@ -139,6 +145,8 @@ fn add(rt: &Runtime) -> Result<()> { .context("This is most likely a BUG, please report!")?; } } + + rt.report_touched(annotation.get_location())?; } else { debug!("No entries to annotate"); } @@ -176,7 +184,7 @@ fn remove(rt: &Runtime) -> Result<()> { debug!("Not deleting annotation object"); } - Ok(()) + rt.report_touched(entry.get_location()).map_err(Error::from) }) .collect() } @@ -200,7 +208,9 @@ fn list(rt: &Runtime) -> Result<()> { .into_get_iter(rt.store()) .map(|el| el.and_then(|o| o.ok_or_else(|| format_err!("Cannot find entry")))) .enumerate() - .map(|(i, entry)| entry.and_then(|e| list_annotation(&rt, i, e, with_text))) + .map(|(i, entry)| entry.and_then(|e| list_annotation(&rt, i, &e, with_text).map(|_| e))) + .map_report_touched(&rt) + .map_ok(|_| ()) .collect()) }) .flatten() @@ -212,12 +222,14 @@ fn list(rt: &Runtime) -> Result<()> { .into_get_iter() .map(|el| el.and_then(|opt| opt.ok_or_else(|| format_err!("Cannot find entry")))) .enumerate() - .map(|(i, entry)| entry.and_then(|e| list_annotation(&rt, i, e, with_text))) + .map(|(i, entry)| entry.and_then(|e| list_annotation(&rt, i, &e, with_text).map(|_| e))) + .map_report_touched(&rt) + .map_ok(|_| ()) .collect() } } -fn list_annotation<'a>(rt: &Runtime, i: usize, a: FileLockEntry<'a>, with_text: bool) -> Result<()> { +fn list_annotation<'a>(rt: &Runtime, i: usize, a: &FileLockEntry<'a>, with_text: bool) -> Result<()> { if with_text { writeln!(rt.stdout(), "--- {i: >5} | {id}\n{text}\n\n", From cbbbbb59b555d48c54d1feaf6e856fefe4d8dc5d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:30:38 +0200 Subject: [PATCH 4/7] Add id reporting in imag-create Signed-off-by: Matthias Beyer --- bin/core/imag-create/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/core/imag-create/src/lib.rs b/bin/core/imag-create/src/lib.rs index ced6e0ac..c208aa54 100644 --- a/bin/core/imag-create/src/lib.rs +++ b/bin/core/imag-create/src/lib.rs @@ -47,6 +47,7 @@ use clap::App; use libimagrt::runtime::Runtime; use libimagrt::application::ImagApplication; +use libimagrt::iter::ReportTouchedResultEntry; use libimagstore::iter::create::StoreIdCreateIteratorExtension; use libimagstore::iter::retrieve::StoreIdRetrieveIteratorExtension; @@ -65,9 +66,9 @@ impl ImagApplication for ImagCreate { .map(Ok); if force { - ids.into_retrieve_iter(rt.store()).collect::>>() + ids.into_retrieve_iter(rt.store()).map_report_touched(&rt).collect::>>() } else { - ids.into_create_iter(rt.store()).collect::>>() + ids.into_create_iter(rt.store()).map_report_touched(&rt).collect::>>() }.map(|_| ()) } From a5d006ef662048096492ee25eceaf91a322e5875 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:30:38 +0200 Subject: [PATCH 5/7] Add id reporting in imag-category Signed-off-by: Matthias Beyer --- bin/core/imag-category/src/lib.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/bin/core/imag-category/src/lib.rs b/bin/core/imag-category/src/lib.rs index 3a2a867d..27fd2d6b 100644 --- a/bin/core/imag-category/src/lib.rs +++ b/bin/core/imag-category/src/lib.rs @@ -48,10 +48,11 @@ extern crate libimagstore; extern crate libimaginteraction; use failure::Fallible as Result; +use resiter::Map; use clap::App; -use libimagerror::trace::MapErrTrace; use libimagrt::runtime::Runtime; +use libimagrt::iter::ReportTouchedResultEntry; use libimagrt::application::ImagApplication; mod ui; @@ -120,7 +121,9 @@ fn set(rt: &Runtime) -> Result<()> { .map(Ok) .into_get_iter(rt.store()) .map_inner_ok_or_else(|| err_msg("Did not find one entry")) - .and_then_ok(|mut e| e.set_category_checked(rt.store(), &name)) + .and_then_ok(|mut e| e.set_category_checked(rt.store(), &name).map(|_| e)) + .map_report_touched(&rt) + .map_ok(|_| ()) .collect() } @@ -132,9 +135,10 @@ fn get(rt: &Runtime) -> Result<()> { .into_iter() .map(Ok) .into_get_iter(rt.store()) - .map(|el| el.and_then(|o| o.ok_or_else(|| err_msg("Did not find one entry")))) - .map(|entry| entry.and_then(|e| e.get_category())) - .map(|name| name.and_then(|n| writeln!(outlock, "{}", n).map_err(Error::from))) + .map_inner_ok_or_else(|| err_msg("Did not find one entry")) + .map_report_touched(&rt) + .and_then_ok(|e| e.get_category()) + .and_then_ok(|n| writeln!(outlock, "{}", n).map_err(Error::from)) .collect() } @@ -147,8 +151,8 @@ fn list_category(rt: &Runtime) -> Result<()> { let mut outlock = out.lock(); category - .get_entries(rt.store()) - .map_err_trace_exit_unwrap() + .get_entries(rt.store())? + .map_report_touched(&rt) .map(|entry| writeln!(outlock, "{}", entry?.get_location()).map_err(Error::from)) .collect() } else { @@ -159,7 +163,9 @@ fn list_category(rt: &Runtime) -> Result<()> { fn create_category(rt: &Runtime) -> Result<()> { let scmd = rt.cli().subcommand_matches("create-category").unwrap(); // safed by main() let name = scmd.value_of("create-category-name").map(String::from).unwrap(); // safed by clap - rt.store().create_category(&name).map(|_| ()) + rt.store() + .create_category(&name) + .and_then(|e| rt.report_touched(e.get_location()).map_err(Error::from)) } fn delete_category(rt: &Runtime) -> Result<()> { @@ -175,7 +181,7 @@ fn delete_category(rt: &Runtime) -> Result<()> { if answer { info!("Deleting category '{}'", name); - rt.store().delete_category(&name).map(|_| ()) + rt.store().delete_category(&name) } else { info!("Not doing anything"); Ok(()) @@ -188,7 +194,7 @@ fn list_categories(rt: &Runtime) -> Result<()> { rt.store() .all_category_names()? - .map(|name| name.and_then(|n| writeln!(outlock, "{}", n).map_err(Error::from))) + .and_then_ok(|n| writeln!(outlock, "{}", n).map_err(Error::from)) .collect() } From 57a8341b9cb17a6bc16572f0e952443c98b00302 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:30:38 +0200 Subject: [PATCH 6/7] Add id reporting in imag-edit Signed-off-by: Matthias Beyer --- bin/core/imag-edit/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/core/imag-edit/src/lib.rs b/bin/core/imag-edit/src/lib.rs index 85d005fe..10a00fea 100644 --- a/bin/core/imag-edit/src/lib.rs +++ b/bin/core/imag-edit/src/lib.rs @@ -49,6 +49,7 @@ use libimagentryedit::edit::Edit; use libimagentryedit::edit::EditHeader; use libimagrt::runtime::Runtime; use libimagrt::application::ImagApplication; +use libimagrt::iter::ReportTouchedResultEntry; use libimagstore::iter::get::StoreIdGetIteratorExtension; use failure::Fallible as Result; @@ -76,6 +77,7 @@ impl ImagApplication for ImagEdit { .into_get_iter(rt.store()) .map_inner_ok_or_else(|| err_msg("Did not find one entry")) .inspect(|e| debug!("Editing = {:?}", e)) + .map_report_touched(&rt) .and_then_ok(|mut entry| { if edit_header { entry.edit_header_and_content(&rt) From 18ec736503af2f8042f6d64615ab28f65d1d5e8c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 26 Oct 2019 20:30:38 +0200 Subject: [PATCH 7/7] Add id reporting in imag-grep Signed-off-by: Matthias Beyer --- bin/core/imag-grep/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/core/imag-grep/src/lib.rs b/bin/core/imag-grep/src/lib.rs index ae75759b..8a04eaf3 100644 --- a/bin/core/imag-grep/src/lib.rs +++ b/bin/core/imag-grep/src/lib.rs @@ -95,6 +95,7 @@ impl ImagApplication for ImagGrep { .and_then_ok(|entry| { if pattern.is_match(entry.get_content()) { debug!("Matched: {}", entry.get_location()); + rt.report_touched(entry.get_location())?; show(&rt, &entry, &pattern, &opts, &mut count) } else { debug!("Not matched: {}", entry.get_location());