Merge pull request #1471 from matthiasbeyer/libimagstore/store-entries-do-not-collect
libimagstore: Do not collect in Iterators
This commit is contained in:
commit
195d921218
40 changed files with 317 additions and 361 deletions
|
@ -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(|| {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<_>>();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -17,111 +17,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//
|
||||
|
||||
macro_rules! mk_iterator {
|
||||
{
|
||||
modname = $modname:ident,
|
||||
itername = $itername:ident,
|
||||
iteryield = $yield:ty,
|
||||
extname = $extname:ident,
|
||||
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 std::result::Result as RResult;
|
||||
|
||||
pub struct $resultitername<'a, I>(I, &'a Store);
|
||||
|
||||
impl<'a, I, E> Iterator for $resultitername<'a, I>
|
||||
where I: Iterator<Item = RResult<StoreId, E>>
|
||||
{
|
||||
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 trait $resultextname<'a> : Iterator {
|
||||
fn $extfnname(self, store: &'a Store) -> $resultitername<'a, Self>
|
||||
where Self: Sized
|
||||
{
|
||||
$resultitername(self, store)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I> $resultextname<'a> for I
|
||||
where I: Iterator
|
||||
{ /* empty */ }
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
modname = $modname:ident,
|
||||
itername = $itername:ident,
|
||||
|
@ -131,13 +27,47 @@ macro_rules! mk_iterator_mod {
|
|||
fun = $fun:expr
|
||||
} => {
|
||||
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 $itername<'a, E>(Box<Iterator<Item = RResult<StoreId, E>> + 'a>, &'a Store)
|
||||
where E: From<StoreError>;
|
||||
|
||||
impl<'a, E> $itername<'a, E>
|
||||
where E: From<StoreError>
|
||||
{
|
||||
pub fn new(inner: Box<Iterator<Item = RResult<StoreId, E>> + 'a>, store: &'a Store) -> Self {
|
||||
$itername(inner, 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))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait $extname<'a, E>
|
||||
where E: From<StoreError>
|
||||
{
|
||||
fn $extfnname(self, store: &'a Store) -> $itername<'a, E>;
|
||||
}
|
||||
|
||||
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)]
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ impl<'a> Iterator for ContactIter<'a> {
|
|||
loop {
|
||||
match self.0.next() {
|
||||
None => return None,
|
||||
Some(sid) => match self.1.get(sid.clone()).map_err(From::from) {
|
||||
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) {
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) => {
|
||||
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,7 +142,9 @@ impl Iterator for DiaryNameIterator {
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
while let Some(next) = self.0.next() {
|
||||
if next.is_in_collection(&["diary"]) {
|
||||
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)
|
||||
|
@ -150,7 +153,8 @@ impl Iterator for DiaryNameIterator {
|
|||
.nth(1)
|
||||
.and_then(|n| n.split("/").nth(0).map(String::from))
|
||||
.ok_or(DE::from_kind(DEK::DiaryNameFindingError))
|
||||
}))
|
||||
}));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,9 @@ 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]) {
|
||||
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,
|
||||
|
@ -45,6 +47,7 @@ impl<'a> Iterator for TimeTrackingsGetIterator<'a> {
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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,8 +44,12 @@ 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 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,
|
||||
|
@ -52,9 +57,8 @@ impl<'a> Iterator for AnnotationIter<'a> {
|
|||
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
|
||||
Ok(None) => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -60,6 +60,9 @@ impl<'a> Iterator for CategoryNameIter<'a> {
|
|||
let query = CATEGORY_REGISTER_NAME_FIELD_PATH;
|
||||
|
||||
while let Some(sid) = self.1.next() {
|
||||
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
|
||||
|
@ -72,6 +75,8 @@ impl<'a> Iterator for CategoryNameIter<'a> {
|
|||
};
|
||||
|
||||
return Some(func(&self.0))
|
||||
}
|
||||
},
|
||||
} // else continue
|
||||
}
|
||||
|
||||
|
@ -92,6 +97,9 @@ impl<'a> Iterator for CategoryEntryIterator<'a> {
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
while let Some(next) = self.1.next() {
|
||||
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)?
|
||||
|
@ -110,6 +118,8 @@ impl<'a> Iterator for CategoryEntryIterator<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue