summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-05-01 22:14:26 +0200
committerGitHub <noreply@github.com>2018-05-01 22:14:26 +0200
commit195d921218559f98844e52cca2ebdfe12fcf6b71 (patch)
tree2000391b30333c74ac1677442c53e436bfacf3d5
parentd45eef299e147d503746adbddf130cd8a3a45a7b (diff)
parent972327e35e6bbabd975ae0aa7e4a202eac95f3c6 (diff)
downloadimag-195d921218559f98844e52cca2ebdfe12fcf6b71.zip
imag-195d921218559f98844e52cca2ebdfe12fcf6b71.tar.gz
Merge pull request #1471 from matthiasbeyer/libimagstore/store-entries-do-not-collect
libimagstore: Do not collect in Iterators
-rw-r--r--bin/core/imag-edit/src/main.rs2
-rw-r--r--bin/core/imag-ids/src/main.rs2
-rw-r--r--bin/core/imag-link/src/main.rs8
-rw-r--r--bin/core/imag-mv/src/main.rs8
-rw-r--r--bin/core/imag-view/src/main.rs29
-rw-r--r--bin/domain/imag-diary/src/list.rs2
-rw-r--r--bin/domain/imag-diary/src/view.rs3
-rw-r--r--bin/domain/imag-habit/src/main.rs8
-rw-r--r--bin/domain/imag-mail/src/main.rs2
-rw-r--r--bin/domain/imag-todo/src/main.rs3
-rw-r--r--bin/domain/imag-wiki/src/main.rs2
-rw-r--r--lib/core/libimagrt/src/runtime.rs3
-rw-r--r--lib/core/libimagstore/src/file_abstraction/fs.rs15
-rw-r--r--lib/core/libimagstore/src/file_abstraction/inmemory.rs6
-rw-r--r--lib/core/libimagstore/src/file_abstraction/iter.rs43
-rw-r--r--lib/core/libimagstore/src/file_abstraction/mod.rs2
-rw-r--r--lib/core/libimagstore/src/iter.rs148
-rw-r--r--lib/core/libimagstore/src/store.rs104
-rw-r--r--lib/core/libimagstore/src/storeid.rs24
-rw-r--r--lib/domain/libimagcontact/src/iter.rs5
-rw-r--r--lib/domain/libimagcontact/src/store.rs5
-rw-r--r--lib/domain/libimagdiary/src/diary.rs20
-rw-r--r--lib/domain/libimagdiary/src/iter.rs32
-rw-r--r--lib/domain/libimaghabit/src/habit.rs3
-rw-r--r--lib/domain/libimaghabit/src/iter.rs20
-rw-r--r--lib/domain/libimagnotes/src/iter.rs11
-rw-r--r--lib/domain/libimagtimetrack/src/iter/get.rs15
-rw-r--r--lib/domain/libimagtimetrack/src/iter/mod.rs4
-rw-r--r--lib/domain/libimagtodo/src/iter.rs10
-rw-r--r--lib/domain/libimagwiki/src/wiki.rs9
-rw-r--r--lib/entry/libimagentryannotation/src/annotateable.rs2
-rw-r--r--lib/entry/libimagentryannotation/src/iter.rs28
-rw-r--r--lib/entry/libimagentrycategory/src/category.rs2
-rw-r--r--lib/entry/libimagentrycategory/src/iter.rs62
-rw-r--r--lib/entry/libimagentrycategory/src/store.rs3
-rw-r--r--lib/entry/libimagentrydatetime/src/datetime.rs5
-rw-r--r--lib/entry/libimagentrygps/src/entry.rs3
-rw-r--r--lib/entry/libimagentrylink/src/external.rs3
-rw-r--r--lib/entry/libimagentrylink/src/internal.rs3
-rw-r--r--lib/entry/libimagentrymarkdown/src/processor.rs3
40 files changed, 309 insertions, 353 deletions
diff --git a/bin/core/imag-edit/src/main.rs b/bin/core/imag-edit/src/main.rs
index 4b6387d..46c4c3f 100644
--- a/bin/core/imag-edit/src/main.rs
+++ b/bin/core/imag-edit/src/main.rs
@@ -89,7 +89,7 @@ fn main() {
let edit_header = rt.cli().is_present("edit-header");
let edit_header_only = rt.cli().is_present("edit-header-only");
- StoreIdIterator::new(Box::new(sids.into_iter()))
+ StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
.into_get_iter(rt.store())
.trace_unwrap_exit(1)
.map(|o| o.unwrap_or_else(|| {
diff --git a/bin/core/imag-ids/src/main.rs b/bin/core/imag-ids/src/main.rs
index 08beb46..240a03e 100644
--- a/bin/core/imag-ids/src/main.rs
+++ b/bin/core/imag-ids/src/main.rs
@@ -45,6 +45,7 @@ use filters::filter::Filter;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
+use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagstore::storeid::StoreId;
@@ -86,6 +87,7 @@ fn main() {
rt.store()
.entries()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter(|id| collection_filter.filter(id))
.map(|id| if print_storepath {
id
diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs
index 4dd8e0d..46ce39e 100644
--- a/bin/core/imag-link/src/main.rs
+++ b/bin/core/imag-link/src/main.rs
@@ -54,7 +54,6 @@ extern crate libimagutil;
use std::io::Write;
use std::path::PathBuf;
-use std::process::exit;
use libimagentrylink::external::ExternalLinker;
use libimagentrylink::internal::InternalLinker;
@@ -255,12 +254,11 @@ fn unlink(rt: &Runtime) {
.map(PathBuf::from)
.collect::<Vec<PathBuf>>().into_iter() // for lifetime inference
.map(StoreId::new_baseless)
- .unwrap_with(|e| { trace_error(&e); exit(1) })
.into_get_iter(rt.store())
- .unwrap_with(|e| { trace_error(&e); exit(1) })
- .filter_map(|e| e)
+ .trace_unwrap_exit(1)
+ .filter_map(|x| x)
.map(|mut entry| entry.unlink(rt.store()))
- .unwrap_with(|e| { trace_error(&e); exit(1) })
+ .trace_unwrap_exit(1)
.collect::<Vec<_>>();
}
diff --git a/bin/core/imag-mv/src/main.rs b/bin/core/imag-mv/src/main.rs
index fbb5021..aeac022 100644
--- a/bin/core/imag-mv/src/main.rs
+++ b/bin/core/imag-mv/src/main.rs
@@ -49,9 +49,11 @@ use std::path::PathBuf;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
+use libimagerror::iter::TraceIterator;
use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
+use libimagstore::error::StoreError;
use libimagentrylink::internal::InternalLinker;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
@@ -91,11 +93,11 @@ fn main() {
})
.get_internal_links()
.map_err_trace_exit_unwrap(1)
- .map(|link| link.get_store_id().clone())
+ .map(|link| Ok(link.get_store_id().clone()) as Result<_, StoreError>)
.into_get_iter(rt.store())
+ .trace_unwrap_exit(1)
.map(|e| {
- e.map_err_trace_exit_unwrap(1)
- .unwrap_or_else(|| {
+ e.unwrap_or_else(|| {
error!("Linked entry does not exist");
exit(1)
})
diff --git a/bin/core/imag-view/src/main.rs b/bin/core/imag-view/src/main.rs
index 5cafb00..bef7e2b 100644
--- a/bin/core/imag-view/src/main.rs
+++ b/bin/core/imag-view/src/main.rs
@@ -68,10 +68,10 @@ use libimagentryview::builtin::md::MarkdownViewer;
use libimagentryview::viewer::Viewer;
use libimagentryview::error::ViewError as VE;
use libimagstore::storeid::IntoStoreId;
+use libimagstore::storeid::StoreIdIterator;
use libimagstore::error::StoreError;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagstore::store::FileLockEntry;
-use libimagstore::storeid::StoreId;
mod ui;
use ui::build_ui;
@@ -89,11 +89,10 @@ fn main() {
if rt.cli().is_present("in") {
let files = entry_ids
- .into_iter()
.into_get_iter(rt.store())
+ .trace_unwrap_exit(1)
.map(|e| {
- e.map_err_trace_exit_unwrap(1)
- .ok_or_else(|| String::from("Entry not found"))
+ e.ok_or_else(|| String::from("Entry not found"))
.map_err(StoreError::from)
.map_err_trace_exit_unwrap(1)
})
@@ -175,7 +174,6 @@ fn main() {
drop(files);
} else {
let iter = entry_ids
- .into_iter()
.into_get_iter(rt.store())
.map(|e| {
e.map_err_trace_exit_unwrap(1)
@@ -249,13 +247,13 @@ fn main() {
}
}
-fn entry_ids(rt: &Runtime) -> Vec<StoreId> {
+fn entry_ids(rt: &Runtime) -> StoreIdIterator {
match rt.cli().values_of("id") {
- Some(pathes) => pathes
- .map(PathBuf::from)
- .map(PathBuf::into_storeid)
- .trace_unwrap_exit(1)
- .collect(),
+ Some(p) => {
+ let pathes : Vec<String> = p.map(String::from).collect();
+ let iter = pathes.into_iter().map(PathBuf::from).map(PathBuf::into_storeid);
+ StoreIdIterator::new(Box::new(iter))
+ },
None => if rt.cli().is_present("entries-from-stdin") {
let stdin = rt.stdin().unwrap_or_else(|| {
@@ -269,11 +267,10 @@ fn entry_ids(rt: &Runtime) -> Vec<StoreId> {
::std::process::exit(1)
});
- buf.lines()
- .map(PathBuf::from)
- .map(PathBuf::into_storeid)
- .trace_unwrap_exit(1)
- .collect()
+ let lines : Vec<String> = buf.lines().map(String::from).collect();
+ let iter = lines.into_iter().map(PathBuf::from).map(PathBuf::into_storeid);
+
+ StoreIdIterator::new(Box::new(iter))
} else {
error!("Something weird happened. I was not able to find the path of the entries to edit");
::std::process::exit(1)
diff --git a/bin/domain/imag-diary/src/list.rs b/bin/domain/imag-diary/src/list.rs
index 55ab274..a40cd0f 100644
--- a/bin/domain/imag-diary/src/list.rs
+++ b/bin/domain/imag-diary/src/list.rs
@@ -23,6 +23,7 @@ use libimagdiary::diary::Diary;
use libimagrt::runtime::Runtime;
use libimagutil::warn_exit::warn_exit;
use libimagerror::trace::MapErrTrace;
+use libimagerror::iter::TraceIterator;
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagutil::debug_result::*;
@@ -40,6 +41,7 @@ pub fn list(rt: &Runtime) {
let mut ids = Diary::entries(rt.store(), &diaryname)
.map_dbg_str("Ok")
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.map(|id| DiaryId::from_storeid(&id))
.collect::<Result<Vec<_>>>()
.map_err_trace_exit_unwrap(1);
diff --git a/bin/domain/imag-diary/src/view.rs b/bin/domain/imag-diary/src/view.rs
index 7e48fd9..763d245 100644
--- a/bin/domain/imag-diary/src/view.rs
+++ b/bin/domain/imag-diary/src/view.rs
@@ -21,6 +21,7 @@ use libimagdiary::diary::Diary;
use libimagdiary::viewer::DiaryViewer as DV;
use libimagrt::runtime::Runtime;
use libimagerror::trace::MapErrTrace;
+use libimagerror::iter::TraceIterator;
use libimagutil::warn_exit::warn_exit;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagentryview::viewer::Viewer;
@@ -34,7 +35,7 @@ pub fn view(rt: &Runtime) {
let entries = Diary::entries(rt.store(), &diaryname)
.map_err_trace_exit_unwrap(1)
.into_get_iter(rt.store())
- .filter_map(Result::ok)
+ .trace_unwrap_exit(1)
.map(|e| e.unwrap_or_else(|| {
error!("Failed to fetch entry");
::std::process::exit(1)
diff --git a/bin/domain/imag-habit/src/main.rs b/bin/domain/imag-habit/src/main.rs
index 61b69bd..218a0d6 100644
--- a/bin/domain/imag-habit/src/main.rs
+++ b/bin/domain/imag-habit/src/main.rs
@@ -57,6 +57,7 @@ use prettytable::row::Row;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::{MapErrTrace, trace_error};
+use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimaghabit::store::HabitStore;
@@ -167,6 +168,7 @@ fn delete(rt: &Runtime) {
.store()
.all_habit_templates()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.map(|sid| (sid.clone(), rt.store().get(sid).map_err_trace_exit_unwrap(1))) // get the FileLockEntry
.filter(|&(_, ref habit)| match habit { // filter for name of habit == name we look for
&Some(ref h) => h.habit_name().map_err_trace_exit_unwrap(1) == name,
@@ -198,6 +200,7 @@ fn delete(rt: &Runtime) {
fle
.linked_instances()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(get_instance)
.filter(has_template_name)
.map(instance_location)
@@ -249,6 +252,7 @@ fn today(rt: &Runtime, future: bool) {
.store()
.all_habit_templates()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(|id| match rt.store().get(id.clone()) {
Ok(Some(h)) => Some(h),
Ok(None) => {
@@ -396,6 +400,7 @@ fn list(rt: &Runtime) {
.store()
.all_habit_templates()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(|id| match rt.store().get(id.clone()) {
Ok(Some(h)) => Some(h),
Ok(None) => {
@@ -451,6 +456,7 @@ fn show(rt: &Runtime) {
.store()
.all_habit_templates()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(|id| get_from_store(rt.store(), id))
.filter(|h| h.habit_name().map(|n| name == n).map_err_trace_exit_unwrap(1))
.enumerate()
@@ -474,6 +480,7 @@ fn show(rt: &Runtime) {
let _ = habit
.linked_instances()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(|instance_id| {
debug!("Getting: {:?}", instance_id);
rt.store().get(instance_id).map_err_trace_exit_unwrap(1)
@@ -505,6 +512,7 @@ fn done(rt: &Runtime) {
.store()
.all_habit_templates()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter_map(|id| get_from_store(rt.store(), id))
.filter(|h| {
let due = h.next_instance_date().map_err_trace_exit_unwrap(1);
diff --git a/bin/domain/imag-mail/src/main.rs b/bin/domain/imag-mail/src/main.rs
index e010c46..f36e01c 100644
--- a/bin/domain/imag-mail/src/main.rs
+++ b/bin/domain/imag-mail/src/main.rs
@@ -43,6 +43,7 @@ extern crate libimagutil;
use std::io::Write;
use libimagerror::trace::{MapErrTrace, trace_error};
+use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagmail::mail::Mail;
@@ -143,6 +144,7 @@ fn list(rt: &Runtime) {
let _ = rt.store()
.entries()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.filter(|id| id.is_in_collection(&["mail"]))
.filter_map(|id| {
rt.store()
diff --git a/bin/domain/imag-todo/src/main.rs b/bin/domain/imag-todo/src/main.rs
index cf1d4cc..622bcce 100644
--- a/bin/domain/imag-todo/src/main.rs
+++ b/bin/domain/imag-todo/src/main.rs
@@ -50,6 +50,7 @@ use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::taskstore::TaskStore;
use libimagerror::trace::{MapErrTrace, trace_error};
+use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
@@ -124,7 +125,7 @@ fn list(rt: &Runtime) {
let res = rt.store().all_tasks() // get all tasks
.map(|iter| { // and if this succeeded
// filter out the ones were we can read the uuid
- let uuids : Vec<_> = iter.filter_map(|storeid| {
+ let uuids : Vec<_> = iter.trace_unwrap_exit(1).filter_map(|storeid| {
match rt.store().retrieve(storeid) {
Ok(fle) => {
match fle.get_header().read_string("todo.uuid") {
diff --git a/bin/domain/imag-wiki/src/main.rs b/bin/domain/imag-wiki/src/main.rs
index 5c393bc..6e58600 100644
--- a/bin/domain/imag-wiki/src/main.rs
+++ b/bin/domain/imag-wiki/src/main.rs
@@ -34,6 +34,7 @@ use std::io::Write;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
+use libimagerror::iter::TraceIterator;
use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
@@ -90,6 +91,7 @@ fn ids(rt: &Runtime, wiki_name: &str) {
})
.all_ids()
.map_err_trace_exit_unwrap(1)
+ .trace_unwrap_exit(1)
.for_each(|id| {
let _ = writeln!(outlock, "{}{}", prefix, id)
.to_exit_code()
diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs
index 8766cda..093bd3c 100644
--- a/lib/core/libimagrt/src/runtime.rs
+++ b/lib/core/libimagrt/src/runtime.rs
@@ -22,6 +22,7 @@ use std::process::Command;
use std::env;
use std::process::exit;
use std::io::Stdin;
+use std::sync::Arc;
pub use clap::App;
use clap::AppSettings;
@@ -132,7 +133,7 @@ impl<'a> Runtime<'a> {
let store_result = if cli_app.use_inmemory_fs() {
Store::new_with_backend(storepath,
&config,
- Box::new(InMemoryFileAbstraction::default()))
+ Arc::new(InMemoryFileAbstraction::default()))
} else {
Store::new(storepath, &config)
};
diff --git a/lib/core/libimagstore/src/file_abstraction/fs.rs b/lib/core/libimagstore/src/file_abstraction/fs.rs
index a41a223..8ee7ee9 100644
--- a/lib/core/libimagstore/src/file_abstraction/fs.rs
+++ b/lib/core/libimagstore/src/file_abstraction/fs.rs
@@ -168,20 +168,15 @@ impl FileAbstraction for FSFileAbstraction {
fn pathes_recursively(&self, basepath: PathBuf) -> Result<PathIterator, SE> {
use walkdir::WalkDir;
- let i : Result<Vec<PathBuf>, SE> = WalkDir::new(basepath)
+ let i = WalkDir::new(basepath)
.min_depth(1)
+ .max_open(100)
.into_iter()
.map(|r| {
- r.map(|e| PathBuf::from(e.path()))
- .chain_err(|| SE::from_kind(SEK::FileError))
- })
- .fold(Ok(vec![]), |acc, e| {
- acc.and_then(move |mut a| {
- a.push(e?);
- Ok(a)
- })
+ r.map(|e| PathBuf::from(e.path())).chain_err(|| SE::from_kind(SEK::FileError))
});
- Ok(PathIterator::new(Box::new(i?.into_iter())))
+
+ Ok(PathIterator::new(Box::new(i)))
}
}
diff --git a/lib/core/libimagstore/src/file_abstraction/inmemory.rs b/lib/core/libimagstore/src/file_abstraction/inmemory.rs
index efe0c4f..495286f 100644
--- a/lib/core/libimagstore/src/file_abstraction/inmemory.rs
+++ b/lib/core/libimagstore/src/file_abstraction/inmemory.rs
@@ -183,15 +183,15 @@ impl FileAbstraction for InMemoryFileAbstraction {
fn pathes_recursively(&self, _basepath: PathBuf) -> Result<PathIterator, SE> {
debug!("Getting all pathes");
- let keys : Vec<PathBuf> = self
+ let keys : Vec<Result<PathBuf, SE>> = self
.backend()
.lock()
.map_err(|_| SE::from_kind(SEK::FileError))?
.get_mut()
.keys()
.map(PathBuf::from)
- .collect();
- // we collect here as this happens only in tests and in memory anyways, so no problem
+ .map(Ok)
+ .collect(); // we have to collect() because of the lock() above.
Ok(PathIterator::new(Box::new(keys.into_iter())))
}
diff --git a/lib/core/libimagstore/src/file_abstraction/iter.rs b/lib/core/libimagstore/src/file_abstraction/iter.rs
index ca2862b..dea30a5 100644
--- a/lib/core/libimagstore/src/file_abstraction/iter.rs
+++ b/lib/core/libimagstore/src/file_abstraction/iter.rs
@@ -18,20 +18,31 @@
//
use std::path::PathBuf;
+use std::sync::Arc;
+
+use error::Result;
+use storeid::StoreId;
+use file_abstraction::FileAbstraction;
/// A wrapper for an iterator over `PathBuf`s
-pub struct PathIterator(Box<Iterator<Item = PathBuf>>);
+pub struct PathIterator(Box<Iterator<Item = Result<PathBuf>>>);
impl PathIterator {
- pub fn new(iter: Box<Iterator<Item = PathBuf>>) -> PathIterator {
+ pub fn new(iter: Box<Iterator<Item = Result<PathBuf>>>) -> PathIterator {
PathIterator(iter)
}
+ pub fn store_id_constructing(self, storepath: PathBuf, backend: Arc<FileAbstraction>)
+ -> StoreIdConstructingIterator
+ {
+ StoreIdConstructingIterator(self, storepath, backend)
+ }
+
}
impl Iterator for PathIterator {
- type Item = PathBuf;
+ type Item = Result<PathBuf>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
@@ -39,3 +50,29 @@ impl Iterator for PathIterator {
}
+
+/// Helper type for constructing StoreIds from a PathIterator.
+///
+/// Automatically ignores non-files.
+pub struct StoreIdConstructingIterator(PathIterator, PathBuf, Arc<FileAbstraction>);
+
+impl Iterator for StoreIdConstructingIterator {
+ type Item = Result<StoreId>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ while let Some(next) = self.0.next() {
+ match next {
+ Err(e) => return Some(Err(e)),
+ Ok(next) => match self.2.exists(&next) {
+ Err(e) => return Some(Err(e)),
+ Ok(true) => return Some(StoreId::from_full_path(&self.1, next)),
+ Ok(false) => { continue },
+ }
+ }
+ }
+
+ None
+ }
+
+}
+
diff --git a/lib/core/libimagstore/src/file_abstraction/mod.rs b/lib/core/libimagstore/src/file_abstraction/mod.rs
index 893b8ca..a317273 100644
--- a/lib/core/libimagstore/src/file_abstraction/mod.rs
+++ b/lib/core/libimagstore/src/file_abstraction/mod.rs
@@ -27,7 +27,7 @@ use storeid::StoreId;
mod fs;
mod inmemory;
-mod iter;
+pub(crate) mod iter;
pub use self::fs::FSFileAbstraction;
pub use self::fs::FSFileAbstractionInstance;
diff --git a/lib/core/libimagstore/src/iter.rs b/lib/core/libimagstore/src/iter.rs
index 0171a93..0e066b0 100644
--- a/lib/core/libimagstore/src/iter.rs
+++ b/lib/core/libimagstore/src/iter.rs
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
-macro_rules! mk_iterator {
+macro_rules! mk_iterator_mod {
{
modname = $modname:ident,
itername = $itername:ident,
@@ -26,118 +26,48 @@ macro_rules! mk_iterator {
extfnname = $extfnname:ident,
fun = $fun:expr
} => {
- use storeid::StoreId;
- #[allow(unused_imports)]
- use store::FileLockEntry;
- use store::Store;
- use error::Result;
-
- pub struct $itername<'a>(Box<Iterator<Item = StoreId> + 'a>, &'a Store);
-
- impl<'a> $itername<'a> {
- pub fn new(inner: Box<Iterator<Item = StoreId> + 'a>, store: &'a Store) -> Self {
- $itername(inner, store)
- }
- }
-
- impl<'a> Iterator for $itername<'a> {
- type Item = Result<$yield>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next().map(|id| $fun(id, self.1))
- }
- }
-
- pub trait $extname<'a> {
- fn $extfnname(self, store: &'a Store) -> $itername<'a>;
- }
-
- impl<'a, I> $extname<'a> for I
- where I: Iterator<Item = StoreId> + 'a
- {
- fn $extfnname(self, store: &'a Store) -> $itername<'a> {
- $itername(Box::new(self), store)
- }
- }
- }
-}
-
-use error::StoreError;
-
-pub enum ExtensionError<E> {
- Forwarded(E),
- StoreError(StoreError)
-}
-
-macro_rules! mk_iterator_mod {
- {
- modname = $modname:ident,
- itername = $itername:ident,
- iteryield = $yield:ty,
- extname = $extname:ident,
- extfnname = $extfnname:ident,
- fun = $fun:expr,
- resultitername = $resultitername:ident,
- resultextname = $resultextname:ident
- } => {
pub mod $modname {
- mk_iterator! {
- modname = $modname,
- itername = $itername,
- iteryield = $yield,
- extname = $extname,
- extfnname = $extfnname,
- fun = $fun
- }
-
+ use storeid::StoreId;
+ #[allow(unused_imports)]
+ use store::FileLockEntry;
+ use store::Store;
+ use error::StoreError;
use std::result::Result as RResult;
- pub struct $resultitername<'a, I>(I, &'a Store);
+ pub struct $itername<'a, E>(Box<Iterator<Item = RResult<StoreId, E>> + 'a>, &'a Store)
+ where E: From<StoreError>;
- impl<'a, I, E> Iterator for $resultitername<'a, I>
- where I: Iterator<Item = RResult<StoreId, E>>
+ impl<'a, E> $itername<'a, E>
+ where E: From<StoreError>
{
- type Item = RResult<$yield, $crate::iter::ExtensionError<E>>;
-
- fn next(&mut self) -> Option<Self::Item> {
- match self.0.next() {
- Some(Ok(sid)) => Some($fun(sid, self.1).map_err($crate::iter::ExtensionError::StoreError)),
- Some(Err(e)) => Some(Err($crate::iter::ExtensionError::Forwarded(e))),
- None => None,
- }
+ pub fn new(inner: Box<Iterator<Item = RResult<StoreId, E>> + 'a>, store: &'a Store) -> Self {
+ $itername(inner, store)
}
}
- pub trait $resultextname<'a> : Iterator {
- fn $extfnname(self, store: &'a Store) -> $resultitername<'a, Self>
- where Self: Sized
- {
- $resultitername(self, store)
+ impl<'a, E> Iterator for $itername<'a, E>
+ where E: From<StoreError>
+ {
+ type Item = RResult<$yield, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|id| $fun(id?, self.1).map_err(E::from))
}
}
- impl<'a, I> $resultextname<'a> for I
- where I: Iterator
- { /* empty */ }
- }
- };
+ pub trait $extname<'a, E>
+ where E: From<StoreError>
+ {
+ fn $extfnname(self, store: &'a Store) -> $itername<'a, E>;
+ }
- {
- modname = $modname:ident,
- itername = $itername:ident,
- iteryield = $yield:ty,
- extname = $extname:ident,
- extfnname = $extfnname:ident,
- fun = $fun:expr
- } => {
- pub mod $modname {
- mk_iterator! {
- modname = $modname,
- itername = $itername,
- iteryield = $yield,
- extname = $extname,
- extfnname = $extfnname,
- fun = $fun
+ impl<'a, I, E> $extname<'a, E> for I
+ where I: Iterator<Item = RResult<StoreId, E>> + 'a,
+ E: From<StoreError>
+ {
+ fn $extfnname(self, store: &'a Store) -> $itername<'a, E> {
+ $itername(Box::new(self), store)
+ }
}
}
}
@@ -149,9 +79,7 @@ mk_iterator_mod! {
iteryield = FileLockEntry<'a>,
extname = StoreIdCreateIteratorExtension,
extfnname = into_create_iter,
- fun = |id: StoreId, store: &'a Store| store.create(id),
- resultitername = StoreCreateResultIterator,
- resultextname = StoreIdCreateResultIteratorExtension
+ fun = |id: StoreId, store: &'a Store| store.create(id)
}
mk_iterator_mod! {
@@ -160,9 +88,7 @@ mk_iterator_mod! {
iteryield = (),
extname = StoreIdDeleteIteratorExtension,
extfnname = into_delete_iter,
- fun = |id: StoreId, store: &'a Store| store.delete(id),
- resultitername = StoreDeleteResultIterator,
- resultextname = StoreIdDeleteResultIteratorExtension
+ fun = |id: StoreId, store: &'a Store| store.delete(id)
}
mk_iterator_mod! {
@@ -171,9 +97,7 @@ mk_iterator_mod! {
iteryield = Option<FileLockEntry<'a>>,
extname = StoreIdGetIteratorExtension,
extfnname = into_get_iter,
- fun = |id: StoreId, store: &'a Store| store.get(id),
- resultitername = StoreGetResultIterator,
- resultextname = StoreIdGetResultIteratorExtension
+ fun = |id: StoreId, store: &'a Store| store.get(id)
}
mk_iterator_mod! {
@@ -182,9 +106,7 @@ mk_iterator_mod! {
iteryield = FileLockEntry<'a>,
extname = StoreIdRetrieveIteratorExtension,
extfnname = into_retrieve_iter,
- fun = |id: StoreId, store: &'a Store| store.retrieve(id),
- resultitername = StoreRetrieveResultIterator,
- resultextname = StoreIdRetrieveResultIteratorExtension
+ fun = |id: StoreId, store: &'a Store| store.retrieve(id)
}
#[cfg(test)]
diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs
index 7edf3f0..44afbea 100644
--- a/lib/core/libimagstore/src/store.rs
+++ b/lib/core/libimagstore/src/store.rs
@@ -137,7 +137,7 @@ impl Iterator for Walk {
impl StoreEntry {
- fn new(id: StoreId, backend: &Box<FileAbstraction>) -> Result<StoreEntry> {
+ fn new(id: StoreId, backend: &Arc<FileAbstraction>) -> Result<StoreEntry> {
let pb = id.clone().into_pathbuf()?;
#[cfg(feature = "fs-lock")]
@@ -214,7 +214,7 @@ pub struct Store {
/// The backend to use
///
/// This provides the filesystem-operation functions (or pretends to)
- backend: Box<FileAbstraction>,
+ backend: Arc<FileAbstraction>,
}
impl Store {
@@ -235,7 +235,7 @@ impl Store {
/// - On success: Store object
///
pub fn new(location: PathBuf, store_config: &Option<Value>) -> Result<Store> {
- let backend = Box::new(FSFileAbstraction::default());
+ let backend = Arc::new(FSFileAbstraction::default());
Store::new_with_backend(location, store_config, backend)
}
@@ -245,7 +245,7 @@ impl Store {
/// Do not use directly, only for testing purposes.
pub fn new_with_backend(location: PathBuf,
store_config: &Option<Value>,
- backend: Box<FileAbstraction>) -> Result<Store> {
+ backend: Arc<FileAbstraction>) -> Result<Store> {
use configuration::*;
debug!("Building new Store object");
@@ -279,33 +279,6 @@ impl Store {
Ok(store)
}
- /// Reset the backend of the store during runtime
- ///
- /// # Warning
- ///
- /// This is dangerous!
- /// You should not be able to do that in application code, only the libimagrt should be used to
- /// do this via safe and careful wrapper functions!
- ///
- /// If you are able to do this without using `libimagrt`, please file an issue report.
- ///
- /// # Purpose
- ///
- /// With the I/O backend of the store, the store is able to pipe itself out via (for example)
- /// JSON. But because we need a functionality where we load contents from the filesystem and
- /// then pipe it to stdout, we need to be able to replace the backend during runtime.
- ///
- /// This also applies the other way round: If we get the store from stdin and have to persist it
- /// to stdout, we need to be able to replace the in-memory backend with the real filesystem
- /// backend.
- ///
- pub fn reset_backend(&mut self, mut backend: Box<FileAbstraction>) -> Result<()> {
- self.backend
- .drain()
- .and_then(|drain| backend.fill(drain))
- .map(|_| self.backend = backend)
- }
-
/// Creates the Entry at the given location (inside the entry)
///
/// # Return value
@@ -741,25 +714,12 @@ impl Store {
}
/// Get _all_ entries in the store (by id as iterator)
- pub fn entries<'a>(&'a self) -> Result<StoreIdIteratorWithStore<'a>> {
+ pub fn entries(&self) -> Result<StoreIdIteratorWithStore> {
self.backend
.pathes_recursively(self.path().clone())
- .and_then(|iter| {
- let mut elems = vec![];
- for element in iter {
- let is_file = {
- let mut base = self.path().clone();
- base.push(element.clone());
- self.backend.is_file(&base)?
- };
-
- if is_file {
- let sid = StoreId::from_full_path(self.path(), element)?;
- elems.push(sid);
- }
- }
- Ok(StoreIdIteratorWithStore::new(Box::new(elems.into_iter()), self))
- })
+ .map(|i| i.store_id_constructing(self.path().clone(), self.backend.clone()))
+ .map(Box::new)
+ .map(|it| StoreIdIteratorWithStore::new(it, self))
}
/// Gets the path where this store is on the disk
@@ -1215,12 +1175,13 @@ Hai
#[cfg(test)]
mod store_tests {
use std::path::PathBuf;
+ use std::sync::Arc;
use super::Store;
use file_abstraction::InMemoryFileAbstraction;
pub fn get_store() -> Store {
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
@@ -1400,50 +1361,5 @@ mod store_tests {
}
}
- #[test]
- fn test_swap_backend_during_runtime() {
- use file_abstraction::InMemoryFileAbstraction;
-
- let mut store = {
- let backend = InMemoryFileAbstraction::default();
- let backend = Box::new(backend);
-
- Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
- };
-
- for n in 1..100 {
- let s = format!("test-{}", n);
- let entry = store.create(PathBuf::from(s.clone())).unwrap();
- assert!(entry.verify().is_ok());
- let loc = entry.get_location().clone().into_pathbuf().unwrap();
- assert!(loc.starts_with("/"));
- assert!(loc.ends_with(s));
- }
-
- {
- let other_backend = InMemoryFileAbstraction::default();
- let other_backend = Box::new(other_backend);
-
- assert!(store.reset_backend(other_backend).is_ok())
- }
-
- for n in 1..100 {
- let s = format!("test-{}", n);
- let entry = store.get(PathBuf::from(s.clone()));
-
- assert!(entry.is_ok());
- let entry = entry.unwrap();
-
- assert!(entry.is_some());
- let entry = entry.unwrap();
-
- assert!(entry.verify().is_ok());
-
- let loc = entry.get_location().clone().into_pathbuf().unwrap();
- assert!(loc.starts_with("/"));
- assert!(loc.ends_with(s));
- }
- }
-
}
diff --git a/lib/core/libimagstore/src/storeid.rs b/lib/core/libimagstore/src/storeid.rs
index 2bcd9ba..3d63979 100644
--- a/lib/core/libimagstore/src/storeid.rs
+++ b/lib/core/libimagstore/src/storeid.rs
@@ -241,7 +241,7 @@ macro_rules! module_entry_path_mod {
}
pub struct StoreIdIterator {
- iter: Box<Iterator<Item = StoreId>>,
+ iter: Box<Iterator<Item = Result<StoreId>>>,
}
impl Debug for StoreIdIterator {
@@ -254,16 +254,16 @@ impl Debug for StoreIdIterator {
impl StoreIdIterator {
- pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
+ pub fn new(iter: Box<Iterator<Item = Result<StoreId>>>) -> StoreIdIterator {
StoreIdIterator { iter }
}
}
impl Iterator for StoreIdIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
- fn next(&mut self) -> Option<StoreId> {
+ fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
@@ -280,16 +280,18 @@ impl<'a> Deref for StoreIdIteratorWithStore<'a> {
}
impl<'a> Iterator for StoreIdIteratorWithStore<'a> {
- type Item = StoreId;
+ type Item = Result<StoreId>;
- fn next(&mut self) -> Option<StoreId> {
+ fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
+use error::StoreError;
+
impl<'a> StoreIdIteratorWithStore<'a> {
- pub fn new(iter: Box<Iterator<Item = StoreId>>, store: &'a Store) -> Self {
+ pub fn new(iter: Box<Iterator<Item = Result<StoreId>>>, store: &'a Store) -> Self {
StoreIdIteratorWithStore(StoreIdIterator::new(iter), store)
}
@@ -300,7 +302,7 @@ impl<'a> StoreIdIteratorWithStore<'a> {
/// Transform the iterator into a StoreCreateIterator
///
/// This immitates the API from `libimagstore::iter`.
- pub fn into_create_iter(self) -> StoreCreateIterator<'a> {
+ pub fn into_create_iter(self) -> StoreCreateIterator<'a, StoreError> {
StoreCreateIterator::new(Box::new(self.0), self.1)
}
@@ -308,7 +310,7 @@ impl<'a> StoreIdIteratorWithStore<'a> {
///
///
/// This immitates the API from `libimagstore::iter`.
- pub fn into_delete_iter(self) -> StoreDeleteIterator<'a> {
+ pub fn into_delete_iter(self) -> StoreDeleteIterator<'a, StoreError> {
StoreDeleteIterator::new(Box::new(self.0), self.1)
}
@@ -316,7 +318,7 @@ impl<'a> StoreIdIteratorWithStore<'a> {
///
///
/// This immitates the API from `libimagstore::iter`.
- pub fn into_get_iter(self) -> StoreGetIterator<'a> {
+ pub fn into_get_iter(self) -> StoreGetIterator<'a, StoreError> {
StoreGetIterator::new(Box::new(self.0), self.1)
}
@@ -324,7 +326,7 @@ impl<'a> StoreIdIteratorWithStore<'a> {
///
///
/// This immitates the API from `libimagstore::iter`.
- pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a> {
+ pub fn into_retrieve_iter(self) -> StoreRetrieveIterator<'a, StoreError> {
StoreRetrieveIterator::new(Box::new(self.0), self.1)
}
diff --git a/lib/domain/libimagcontact/src/iter.rs b/lib/domain/libimagcontact/src/iter.rs
index 1f99c87..48f0f40 100644
--- a/lib/domain/libimagcontact/src/iter.rs
+++ b/lib/domain/libimagcontact/src/iter.rs
@@ -43,8 +43,9 @@ impl<'a> Iterator for ContactIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.0.next() {
- None => return None,
- Some(sid) => match self.1.get(sid.clone()).map_err(From::from) {
+ None => return None,
+ Some(Err(e)) => return Some(Err(e).map_err(CE::from)),
+ Some(Ok(sid)) => match self.1.get(sid.clone()).map_err(From::from) {
Err(e) => return Some(Err(e)),
Ok(None) => return Some(Err(CE::from_kind(CEK::EntryNotFound(sid)))),
Ok(Some(entry)) => match entry.is_contact().map_err(From::from) {
diff --git a/lib/domain/libimagcontact/src/store.rs b/lib/domain/libimagcontact/src/store.rs
index 88856b7..e2b9aea 100644
--- a/lib/domain/libimagcontact/src/store.rs
+++ b/lib/domain/libimagcontact/src/store.rs
@@ -81,7 +81,10 @@ impl<'a> ContactStore<'a> for Store {
let iter = self
.entries()?
.without_store()
- .filter(|id| id.is_in_collection(&["contact"]));
+ .filter(|id| match *id {
+ Ok(ref id) => id.is_in_collection(&["contact"]),
+ Err(_) => true,
+ });
Ok(StoreIdIterator::new(Box::new(iter)))
}
diff --git a/lib/domain/libimagdiary/src/diary.rs b/lib/domain/libimagdiary/src/diary.rs
index 15ee28b..ea4b249 100644
--- a/lib/domain/libimagdiary/src/diary.rs
+++ b/lib/domain/libimagdiary/src/diary.rs
@@ -94,13 +94,27 @@ impl Diary for Store {
.chain_err(|| DEK::StoreReadError)
}
+ /// get the id of the youngest entry
+ ///
+ /// TODO: We collect internally here. We shouldn't do that. Solution unclear.
fn get_youngest_entry_id(&self, diary_name: &str) -> Option<Result<DiaryId>> {
+ use error::DiaryError as DE;
+
match Diary::entries(self, diary_name) {
Err(e) => Some(Err(e)),
Ok(entries) => {
- entries
- .map(|e| DiaryId::from_storeid(&e))
- .sorted_by(|a, b| {
+ let mut sorted_entries = vec![];
+
+ for entry in entries {
+ let entry = match entry {
+ Ok(e) => DiaryId::from_storeid(&e),
+ Err(e) => return Some(Err(e).map_err(DE::from)),
+ };
+
+ sorted_entries.push(entry);
+ }
+
+ sorted_entries.into_iter().sorted_by(|a, b| {
match (a, b) {
(&Ok(ref a), &Ok(ref b)) => {
let a : NaiveDateTime = a.clone().into();
diff --git a/lib/domain/libimagdiary/src/iter.rs b/lib/domain/libimagdiary/src/iter.rs
index 09f9114..6ebc523 100644
--- a/lib/domain/libimagdiary/src/iter.rs
+++ b/lib/domain/libimagdiary/src/iter.rs
@@ -103,16 +103,17 @@ impl Filter<StoreId> for DiaryEntryIterator {
}
impl Iterator for DiaryEntryIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next() {
- None => return None,
- Some(s) => {
+ None => return None,
+ Some(Err(e)) => return Some(Err(e).map_err(DE::from)),
+ Some(Ok(s)) => {
debug!("Next element: {:?}", s);
if Filter::filter(self, &s) {
- return Some(s)
+ return Some(Ok(s))
} else {
continue
}
@@ -141,16 +142,19 @@ impl Iterator for DiaryNameIterator {
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.0.next() {
- if next.is_in_collection(&["diary"]) {
- return Some(next
- .to_str()
- .chain_err(|| DEK::DiaryNameFindingError)
- .and_then(|s| {
- s.split("diary/")
- .nth(1)
- .and_then(|n| n.split("/").nth(0).map(String::from))
- .ok_or(DE::from_kind(DEK::DiaryNameFindingError))
- }))
+ match next {
+ Err(e) => return Some(Err(e).map_err(DE::from)),
+ Ok(next) => if next.is_in_collection(&["diary"]) {
+ return Some(next
+ .to_str()
+ .chain_err(|| DEK::DiaryNameFindingError)
+ .and_then(|s| {
+ s.split("diary/")
+ .nth(1)
+ .and_then(|n| n.split("/").nth(0).map(String::from))
+ .ok_or(DE::from_kind(DEK::DiaryNameFindingError))
+ }));
+ },
}
}
diff --git a/lib/domain/libimaghabit/src/habit.rs b/lib/domain/libimaghabit/src/habit.rs
index 36c9dcc..cd53c29 100644
--- a/lib/domain/libimaghabit/src/habit.rs
+++ b/lib/domain/libimaghabit/src/habit.rs
@@ -131,7 +131,8 @@ impl HabitTemplate for Entry {
let iter = self
.get_internal_links()?
.map(|link| link.get_store_id().clone())
- .filter(IsHabitCheck::is_habit_instance);
+ .filter(IsHabitCheck::is_habit_instance)
+ .map(Ok);
let sidi = StoreIdIterator::new(Box::new(iter));
Ok(HabitInstanceStoreIdIterator::new(sidi))
diff --git a/lib/domain/libimaghabit/src/iter.rs b/lib/domain/libimaghabit/src/iter.rs
index fa64f1a..6a1af76 100644
--- a/lib/domain/libimaghabit/src/iter.rs
+++ b/lib/domain/libimaghabit/src/iter.rs
@@ -22,16 +22,21 @@ use libimagstore::storeid::StoreIdIteratorWithStore;
use libimagstore::storeid::StoreId;
use util::IsHabitCheck;
+use error::Result;
+use error::HabitError as HE;
pub struct HabitTemplateStoreIdIterator(StoreIdIterator);
impl Iterator for HabitTemplateStoreIdIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(n) = self.0.next() {
- if n.is_habit_template() {
- return Some(n)
+ match n {
+ Ok(n) => if n.is_habit_template() {
+ return Some(Ok(n))
+ },
+ Err(e) => return Some(Err(e).map_err(HE::from)),
}
}
None
@@ -59,12 +64,15 @@ impl HabitInstanceStoreIdIterator {
}
impl Iterator for HabitInstanceStoreIdIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(n) = self.0.next() {
- if n.is_habit_instance() {
- return Some(n)
+ match n {
+ Ok(n) => if n.is_habit_instance() {
+ return Some(Ok(n));
+ },
+ Err(e) => return Some(Err(e).map_err(HE::from)),
}
}
None
diff --git a/lib/domain/libimagnotes/src/iter.rs b/lib/domain/libimagnotes/src/iter.rs
index 263506c..98adbbd 100644
--- a/lib/domain/libimagnotes/src/iter.rs
+++ b/lib/domain/libimagnotes/src/iter.rs
@@ -21,6 +21,8 @@ use libimagstore::storeid::StoreId;
use libimagstore::storeid::StoreIdIterator;
use notestoreid::*;
+use error::Result;
+use error::NoteError as NE;
#[derive(Debug)]
pub struct NoteIterator(StoreIdIterator);
@@ -34,12 +36,15 @@ impl NoteIterator {
}
impl Iterator for NoteIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(n) = self.0.next() {
- if n.is_note_id() {
- return Some(n);
+ match n {
+ Ok(n) => if n.is_note_id() {
+ return Some(Ok(n));
+ },
+ Err(e) => return Some(Err(e).map_err(NE::from)),
}
}
diff --git a/lib/domain/libimagtimetrack/src/iter/get.rs b/lib/domain/libimagtimetrack/src/iter/get.rs
index e043395..fdb55c2 100644
--- a/lib/domain/libimagtimetrack/src/iter/get.rs
+++ b/lib/domain/libimagtimetrack/src/iter/get.rs
@@ -37,12 +37,15 @@ impl<'a> Iterator for TimeTrackingsGetIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.0.next() {
- if next.is_in_collection(&[CRATE_NAME]) {
- return match self.1.get(next) {
- Ok(Some(fle)) => Some(Ok(fle)),
- Ok(None) => continue,
- Err(e) => Some(Err(e))
- };
+ match next {
+ Err(e) => return Some(Err(e)),
+ Ok(next) => if next.is_in_collection(&[CRATE_NAME]) {
+ return match self.1.get(next) {
+ Ok(Some(fle)) => Some(Ok(fle)),
+ Ok(None) => continue,
+ Err(e) => Some(Err(e))
+ };
+ }
}
}
diff --git a/lib/domain/libimagtimetrack/src/iter/mod.rs b/lib/domain/libimagtimetrack/src/iter/mod.rs
index f0648ce..556d8b9 100644
--- a/lib/domain/libimagtimetrack/src/iter/mod.rs
+++ b/lib/domain/libimagtimetrack/src/iter/mod.rs
@@ -26,6 +26,8 @@ pub mod tag;
#[cfg(test)]
mod test {
+ use std::sync::Arc;
+
use chrono::naive::NaiveDate;
use libimagstore::store::Store;
@@ -37,7 +39,7 @@ mod test {
use std::path::PathBuf;
use libimagstore::file_abstraction::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/domain/libimagtodo/src/iter.rs b/lib/domain/libimagtodo/src/iter.rs
index c2871c5..c5c6394 100644
--- a/lib/domain/libimagtodo/src/iter.rs
+++ b/lib/domain/libimagtodo/src/iter.rs
@@ -20,6 +20,9 @@
use libimagstore::storeid::StoreIdIterator;
use libimagstore::storeid::StoreId;
+use error::Result;
+use error::TodoError as TE;
+
pub struct TaskIdIterator(StoreIdIterator);
impl TaskIdIterator {
@@ -31,14 +34,15 @@ impl TaskIdIterator {
}
impl Iterator for TaskIdIterator {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.0.next() {
None => return None,
- Some(n) => if n.is_in_collection(&["todo", "taskwarrior"]) {
- return Some(n)
+ Some(Err(e)) => return Some(Err(e).map_err(TE::from)),
+ Some(Ok(n)) => if n.is_in_collection(&["todo", "taskwarrior"]) {
+ return Some(Ok(n))
}, // else continue
}
}
diff --git a/lib/domain/libimagwiki/src/wiki.rs b/lib/domain/libimagwiki/src/wiki.rs
index 50ef61c..0612bec 100644
--- a/lib/domain/libimagwiki/src/wiki.rs
+++ b/lib/domain/libimagwiki/src/wiki.rs
@@ -108,12 +108,15 @@ impl<'a, 'b> Wiki<'a, 'b> {
pub struct WikiIdIterator<'a>(StoreIdIteratorWithStore<'a>, IdIsInWikiFilter<'a>);
impl<'a> Iterator for WikiIdIterator<'a> {
- type Item = StoreId;
+ type Item = Result<StoreId>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.0.next() {
- if self.1.filter(&next) {
- return Some(next)
+ match next {
+ Ok(next) => if self.1.filter(&next) {
+ return Some(Ok(next));
+ },
+ Err(e) => return Some(Err(e).map_err(WE::from)),
}
}
diff --git a/lib/entry/libimagentryannotation/src/annotateable.rs b/lib/entry/libimagentryannotation/src/annotateable.rs
index 4906b17..d38b9c6 100644
--- a/lib/entry/libimagentryannotation/src/annotateable.rs
+++ b/lib/entry/libimagentryannotation/src/annotateable.rs
@@ -92,7 +92,7 @@ impl Annotateable for Entry {
fn annotations<'a>(&self, store: &'a Store) -> Result<AnnotationIter<'a>> {
self.get_internal_links()
.map_err(From::from)
- .map(|iter| StoreIdIterator::new(Box::new(iter.map(|e| e.get_store_id().clone()))))
+ .map(|iter| StoreIdIterator::new(Box::new(iter.map(|e| e.get_store_id().clone()).map(Ok))))
.map(|i| AnnotationIter::new(i, store))
}
diff --git a/lib/entry/libimagentryannotation/src/iter.rs b/lib/entry/libimagentryannotation/src/iter.rs
index 996c6ff..9485ba0 100644
--- a/lib/entry/libimagentryannotation/src/iter.rs
+++ b/lib/entry/libimagentryannotation/src/iter.rs
@@ -24,6 +24,7 @@ use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreIdIterator;
use error::Result;
+use error::AnnotationError as AE;
use error::AnnotationErrorKind as AEK;
use error::ResultExt;
@@ -43,18 +44,21 @@ impl<'a> Iterator for AnnotationIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
loop {
- match self.0.next().map(|id| self.1.get(id)) {
- Some(Ok(Some(entry))) => {
- match entry.get_header().read_bool("annotation.is_annotation").chain_err(|| AEK::HeaderReadError) {
- Ok(None) => continue, // not an annotation
- Ok(Some(false)) => continue,
- Ok(Some(true)) => return Some(Ok(entry)),
- Err(e) => return Some(Err(e)),
- }
- },
- Some(Ok(None)) => continue,
- Some(Err(e)) => return Some(Err(e).chain_err(|| AEK::StoreReadError)),
- None => return None, // iterator consumed
+ match self.0.next() {
+ None => return None, // iterator consumed
+ Some(Err(e)) => return Some(Err(e).map_err(AE::from)),
+ Some(Ok(id)) => match self.1.get(id) {
+ Err(e) => return Some(Err(e).chain_err(|| AEK::StoreReadError)),
+ Ok(Some(entry)) => {
+ match entry.get_header().read_bool("annotation.is_annotation").chain_err(|| AEK::HeaderReadError) {
+ Ok(None) => continue, // not an annotation
+ Ok(Some(false)) => continue,
+ Ok(Some(true)) => return Some(Ok(entry)),
+ Err(e) => return Some(Err(e)),
+ }
+ },
+ Ok(None) => continue,
+ }
}
}
}
diff --git a/lib/entry/libimagentrycategory/src/category.rs b/lib/entry/libimagentrycategory/src/category.rs
index fab8715..8da3342 100644
--- a/lib/entry/libimagentrycategory/src/category.rs
+++ b/lib/entry/libimagentrycategory/src/category.rs
@@ -55,7 +55,7 @@ impl Category for Entry {
fn get_entries<'a>(&self, store: &'a Store) -> Result<CategoryEntryIterator<'a>> {
trace!("Getting linked entries for category '{:?}'", self.get_location());
- let sit = self.get_internal_links()?.map(|l| l.get_store_id().clone());
+ let sit = self.get_internal_links()?.map(|l| l.get_store_id().clone()).map(Ok);
let sit = StoreIdIterator::new(Box::new(sit));
let name = self.get_name()?;
Ok(CategoryEntryIterator::new(store, sit, name))
diff --git a/lib/entry/libimagentrycategory/src/iter.rs b/lib/entry/libimagentrycategory/src/iter.rs
index a835b82..ac14302 100644
--- a/lib/entry/libimagentrycategory/src/iter.rs
+++ b/lib/entry/libimagentrycategory/src/iter.rs
@@ -60,18 +60,23 @@ impl<'a> Iterator for CategoryNameIter<'a> {
let query = CATEGORY_REGISTER_NAME_FIELD_PATH;
while let Some(sid) = self.1.next() {
- if sid.is_in_collection(&["category"]) {
- let func = |store: &Store| { // hack for returning Some(Result<_, _>)
- store
- .get(sid)?
- .ok_or_else(|| CE::from_kind(CEK::StoreReadError))?
- .get_header()
- .read_string(query)
- .chain_err(|| CEK::HeaderReadError)?
- .ok_or_else(|| CE::from_kind(CEK::StoreReadError))
- };
-
- return Some(func(&self.0))
+ match sid {
+ Err(e) => return Some(Err(e).map_err(CE::from)),
+ Ok(sid) => {
+ if sid.is_in_collection(&["category"]) {
+ let func = |store: &Store| { // hack for returning Some(Result<_, _>)
+ store
+ .get(sid)?
+ .ok_or_else(|| CE::from_kind(CEK::StoreReadError))?
+ .get_header()
+ .read_string(query)
+ .chain_err(|| CEK::HeaderReadError)?
+ .ok_or_else(|| CE::from_kind(CEK::StoreReadError))
+ };
+
+ return Some(func(&self.0))
+ }
+ },
} // else continue
}
@@ -92,20 +97,25 @@ impl<'a> Iterator for CategoryEntryIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.1.next() {
- let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
- let entry = self.0
- .get(next)?
- .ok_or_else(|| CE::from_kind(CEK::StoreReadError))?;
- Ok((entry.get_category()?, entry))
- };
-
- match getter(next) {
- Err(e) => return Some(Err(e)),
- Ok((c, e)) => {
- if c == self.2 {
- return Some(Ok(e))
- // } else {
- // continue
+ match next {
+ Err(e) => return Some(Err(e).map_err(CE::from)),
+ Ok(next) => {
+ let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
+ let entry = self.0
+ .get(next)?
+ .ok_or_else(|| CE::from_kind(CEK::StoreReadError))?;
+ Ok((entry.get_category()?, entry))
+ };
+
+ match getter(next) {
+ Err(e) => return Some(Err(e)),
+ Ok((c, e)) => {
+ if c == self.2 {
+ return Some(Ok(e))
+ // } else {
+ // continue
+ }
+ }
}
}
}
diff --git a/lib/entry/libimagentrycategory/src/store.rs b/lib/entry/libimagentrycategory/src/store.rs
index e1fb929..8179010 100644
--- a/lib/entry/libimagentrycategory/src/store.rs
+++ b/lib/entry/libimagentrycategory/src/store.rs
@@ -111,6 +111,7 @@ impl CategoryStore for Store {
mod tests {
extern crate env_logger;
use std::path::PathBuf;
+ use std::sync::Arc;
use super::*;
@@ -118,7 +119,7 @@ mod tests {
pub fn get_store() -> Store {
use libimagstore::store::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/entry/libimagentrydatetime/src/datetime.rs b/lib/entry/libimagentrydatetime/src/datetime.rs
index 6eb6683..790f9f8 100644
--- a/lib/entry/libimagentrydatetime/src/datetime.rs
+++ b/lib/entry/libimagentrydatetime/src/datetime.rs
@@ -195,7 +195,7 @@ fn val_to_ndt(v: &Value) -> Result<NaiveDateTime> {
#[cfg(test)]
mod tests {
use std::path::PathBuf;
- use toml_query::read::TomlValueReadExt;
+ use std::sync::Arc;
use super::*;
@@ -204,10 +204,11 @@ mod tests {
use chrono::naive::NaiveDateTime;
use chrono::naive::NaiveDate;
use chrono::naive::NaiveTime;
+ use toml_query::read::TomlValueReadExt;
pub fn get_store() -> Store {
use libimagstore::store::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/entry/libimagentrygps/src/entry.rs b/lib/entry/libimagentrygps/src/entry.rs
index 37acb07..d6eb4be 100644
--- a/lib/entry/libimagentrygps/src/entry.rs
+++ b/lib/entry/libimagentrygps/src/entry.rs
@@ -102,6 +102,7 @@ impl GPSEntry for Entry {
#[cfg(test)]
mod tests {
use std::path::PathBuf;
+ use std::sync::Arc;
use libimagstore::store::Store;
@@ -113,7 +114,7 @@ mod tests {
fn get_store() -> Store {
use libimagstore::file_abstraction::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/entry/libimagentrylink/src/external.rs b/lib/entry/libimagentrylink/src/external.rs
index 4d7d48b..2d5592c 100644
--- a/lib/entry/libimagentrylink/src/external.rs
+++ b/lib/entry/libimagentrylink/src/external.rs
@@ -406,6 +406,7 @@ impl ExternalLinker for Entry {
mod tests {
use super::*;
use std::path::PathBuf;
+ use std::sync::Arc;
use libimagstore::store::Store;
@@ -416,7 +417,7 @@ mod tests {
pub fn get_store() -> Store {
use libimagstore::file_abstraction::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/internal.rs
index e7c06fd..480a07b 100644
--- a/lib/entry/libimagentrylink/src/internal.rs
+++ b/lib/entry/libimagentrylink/src/internal.rs
@@ -772,6 +772,7 @@ pub mod store_check {
#[cfg(test)]
mod test {
use std::path::PathBuf;
+ use std::sync::Arc;
use libimagstore::store::Store;
@@ -784,7 +785,7 @@ mod test {
pub fn get_store() -> Store {
use libimagstore::file_abstraction::InMemoryFileAbstraction;
- let backend = Box::new(InMemoryFileAbstraction::default());
+ let backend = Arc::new(InMemoryFileAbstraction::default());
Store::new_with_backend(PathBuf::from("/"), &None, backend).unwrap()
}
diff --git a/lib/entry/libimagentrymarkdown/src/processor.rs b/lib/entry/libimagentrymarkdown/src/processor.rs
index f9b085a..5fddcd9 100644
--- a/lib/entry/libimagentrymarkdown/src/processor.rs
+++ b/lib/entry/libimagentrymarkdown/src/processor.rs
@@ -233,6 +233,7 @@ mod tests {
use super::*;
use std::path::PathBuf;
+ use std::sync::Arc;
use libimagstore::store::Store;
use libimagentrylink::internal::InternalLinker;
@@ -244,7 +245,7 @@ mod tests {
pub fn get_store() -> Store {
use libimagstore::file_abstraction::InMemoryFileAbstraction;
let fs = InMemoryFileAbstraction::default();
- Store::new_with_backend(PathBuf::from("/"), &None, Box::new(fs)).unwrap()
+ Store::new_with_backend(PathBuf::from("/"), &None, Arc::new(fs)).unwrap()
}
#[test]