summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-05-30 17:54:48 +0200
committerMatthias Beyer <mail@beyermatthias.de>2019-05-31 12:48:00 +0200
commit901502b67efd885b2deb9ff1346808689e025f4c (patch)
treec5f1bda7d9af1f774bd54d9d3e34b93e713195e2
parentd02d53594e8b95786f4cff93aab3c87132889bf3 (diff)
Split "internal" module into several submodules
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--bin/core/imag-annotate/src/main.rs2
-rw-r--r--bin/core/imag-diagnostics/src/main.rs2
-rw-r--r--bin/core/imag-link/src/main.rs4
-rw-r--r--bin/core/imag-mv/src/main.rs2
-rw-r--r--bin/domain/imag-bookmark/src/main.rs2
-rw-r--r--bin/domain/imag-wiki/src/main.rs2
-rw-r--r--lib/domain/libimagbookmark/src/collection.rs4
-rw-r--r--lib/domain/libimaghabit/src/habit.rs2
-rw-r--r--lib/domain/libimagwiki/src/wiki.rs2
-rw-r--r--lib/entry/libimagentryannotation/src/annotateable.rs2
-rw-r--r--lib/entry/libimagentrycategory/src/category.rs2
-rw-r--r--lib/entry/libimagentrycategory/src/entry.rs2
-rw-r--r--lib/entry/libimagentrycategory/src/store.rs2
-rw-r--r--lib/entry/libimagentrylink/src/iter.rs97
-rw-r--r--lib/entry/libimagentrylink/src/lib.rs5
-rw-r--r--lib/entry/libimagentrylink/src/link.rs150
-rw-r--r--lib/entry/libimagentrylink/src/linker.rs (renamed from lib/entry/libimagentrylink/src/internal.rs)365
-rw-r--r--lib/entry/libimagentrylink/src/storecheck.rs173
-rw-r--r--lib/entry/libimagentrymarkdown/src/processor.rs4
-rw-r--r--lib/entry/libimagentryurl/src/iter.rs4
-rw-r--r--lib/entry/libimagentryurl/src/linker.rs2
21 files changed, 447 insertions, 383 deletions
diff --git a/bin/core/imag-annotate/src/main.rs b/bin/core/imag-annotate/src/main.rs
index 5904b345..f86d71fa 100644
--- a/bin/core/imag-annotate/src/main.rs
+++ b/bin/core/imag-annotate/src/main.rs
@@ -66,7 +66,7 @@ use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::store::FileLockEntry;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
mod ui;
diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs
index 4414c1b8..5aa6844d 100644
--- a/bin/core/imag-diagnostics/src/main.rs
+++ b/bin/core/imag-diagnostics/src/main.rs
@@ -55,7 +55,7 @@ use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
-use libimagentrylink::internal::*;
+use libimagentrylink::linker::InternalLinker;
use toml::Value;
use toml_query::read::TomlValueReadExt;
diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs
index 226b3a43..df717015 100644
--- a/bin/core/imag-link/src/main.rs
+++ b/bin/core/imag-link/src/main.rs
@@ -63,8 +63,8 @@ use failure::Error;
use failure::err_msg;
use libimagentryurl::linker::UrlLinker;
-use libimagentrylink::internal::InternalLinker;
-use libimagentrylink::internal::store_check::StoreLinkConsistentExt;
+use libimagentrylink::linker::InternalLinker;
+use libimagentrylink::storecheck::StoreLinkConsistentExt;
use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
diff --git a/bin/core/imag-mv/src/main.rs b/bin/core/imag-mv/src/main.rs
index 9f2fde74..9eca7b35 100644
--- a/bin/core/imag-mv/src/main.rs
+++ b/bin/core/imag-mv/src/main.rs
@@ -56,7 +56,7 @@ use libimagerror::exit::ExitUnwrap;
use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
fn main() {
diff --git a/bin/domain/imag-bookmark/src/main.rs b/bin/domain/imag-bookmark/src/main.rs
index b2eaa795..f15ceabe 100644
--- a/bin/domain/imag-bookmark/src/main.rs
+++ b/bin/domain/imag-bookmark/src/main.rs
@@ -61,7 +61,7 @@ use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagutil::debug_result::DebugResult;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
mod ui;
diff --git a/bin/domain/imag-wiki/src/main.rs b/bin/domain/imag-wiki/src/main.rs
index 1556abbb..765a9e64 100644
--- a/bin/domain/imag-wiki/src/main.rs
+++ b/bin/domain/imag-wiki/src/main.rs
@@ -252,7 +252,7 @@ fn show(rt: &Runtime, wiki_name: &str) {
}
fn delete(rt: &Runtime, wiki_name: &str) {
- use libimagentrylink::internal::InternalLinker;
+ use libimagentrylink::linker::InternalLinker;
let scmd = rt.cli().subcommand_matches("delete").unwrap(); // safed by clap
let name = String::from(scmd.value_of("delete-name").unwrap()); // safe by clap
diff --git a/lib/domain/libimagbookmark/src/collection.rs b/lib/domain/libimagbookmark/src/collection.rs
index ec70a6c6..3ebf8066 100644
--- a/lib/domain/libimagbookmark/src/collection.rs
+++ b/lib/domain/libimagbookmark/src/collection.rs
@@ -36,8 +36,8 @@ use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagentryurl::linker::UrlLinker;
use libimagentryurl::iter::UrlIter;
-use libimagentrylink::internal::InternalLinker;
-use libimagentrylink::internal::Link as StoreLink;
+use libimagentrylink::linker::InternalLinker;
+use libimagentrylink::link::Link as StoreLink;
use crate::link::Link;
diff --git a/lib/domain/libimaghabit/src/habit.rs b/lib/domain/libimaghabit/src/habit.rs
index 7041dff7..bd203189 100644
--- a/lib/domain/libimaghabit/src/habit.rs
+++ b/lib/domain/libimaghabit/src/habit.rs
@@ -33,7 +33,7 @@ use crate::util::IsHabitCheck;
use crate::util::get_string_header_from_entry;
use crate::instance::IsHabitInstance;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;
diff --git a/lib/domain/libimagwiki/src/wiki.rs b/lib/domain/libimagwiki/src/wiki.rs
index c61a6962..9cd3d236 100644
--- a/lib/domain/libimagwiki/src/wiki.rs
+++ b/lib/domain/libimagwiki/src/wiki.rs
@@ -22,7 +22,7 @@ use std::path::PathBuf;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagstore::iter::Entries;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use failure::Fallible as Result;
use failure::Error;
diff --git a/lib/entry/libimagentryannotation/src/annotateable.rs b/lib/entry/libimagentryannotation/src/annotateable.rs
index 46b8cdbc..f89ca631 100644
--- a/lib/entry/libimagentryannotation/src/annotateable.rs
+++ b/lib/entry/libimagentryannotation/src/annotateable.rs
@@ -24,7 +24,7 @@ use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use libimagentryutil::isa::Is;
use libimagentryutil::isa::IsKindHeaderPathProvider;
diff --git a/lib/entry/libimagentrycategory/src/category.rs b/lib/entry/libimagentrycategory/src/category.rs
index fb7268a7..f33a7ed5 100644
--- a/lib/entry/libimagentrycategory/src/category.rs
+++ b/lib/entry/libimagentrycategory/src/category.rs
@@ -22,7 +22,7 @@ use libimagentryutil::isa::IsKindHeaderPathProvider;
use libimagstore::store::Entry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use toml_query::read::TomlValueReadTypeExt;
diff --git a/lib/entry/libimagentrycategory/src/entry.rs b/lib/entry/libimagentrycategory/src/entry.rs
index 9876add4..a9e39da0 100644
--- a/lib/entry/libimagentrycategory/src/entry.rs
+++ b/lib/entry/libimagentrycategory/src/entry.rs
@@ -23,7 +23,7 @@ use toml_query::read::TomlValueReadTypeExt;
use toml::Value;
use libimagstore::store::Entry;
-use libimagentrylink::internal::InternalLinker;
+use libimagentrylink::linker::InternalLinker;
use libimagerror::errors::ErrorMsg as EM;
use failure::Fallible as Result;
diff --git a/lib/entry/libimagentrycategory/src/store.rs b/lib/entry/libimagentrycategory/src/store.rs
index 3ea78648..3f0f7df2 100644
--- a/lib/entry/libimagentrycategory/src/store.rs
+++ b/lib/entry/libimagentrycategory/src/store.rs
@@ -84,7 +84,7 @@ impl CategoryStore for Store {
///
/// Automatically removes all category settings from entries which are linked to this category.
fn delete_category(&self, name: &str) -> Result<()> {
- use libimagentrylink::internal::InternalLinker;
+ use libimagentrylink::linker::InternalLinker;
use crate::category::Category;
trace!("Deleting category: '{}'", name);
diff --git a/lib/entry/libimagentrylink/src/iter.rs b/lib/entry/libimagentrylink/src/iter.rs
new file mode 100644
index 00000000..5d76d0b6
--- /dev/null
+++ b/lib/entry/libimagentrylink/src/iter.rs
@@ -0,0 +1,97 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+
+use std::vec::IntoIter;
+
+use failure::Error;
+use failure::ResultExt;
+use failure::Fallible as Result;
+use toml::Value;
+use itertools::Itertools;
+
+use libimagstore::store::Store;
+use libimagstore::store::FileLockEntry;
+use libimagerror::errors::ErrorMsg as EM;
+
+use crate::link::Link;
+
+pub struct LinkIter(IntoIter<Link>);
+
+impl LinkIter {
+
+ pub fn new(v: Vec<Link>) -> LinkIter {
+ LinkIter(v.into_iter())
+ }
+
+ pub fn into_getter(self, store: &Store) -> GetIter {
+ GetIter(self.0, store)
+ }
+
+}
+
+impl Iterator for LinkIter {
+ type Item = Link;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+pub trait IntoValues {
+ fn into_values(self) -> Vec<Result<Value>>;
+}
+
+impl<I: Iterator<Item = Link>> IntoValues for I {
+ fn into_values(self) -> Vec<Result<Value>> {
+ self.map(|s| s.without_base())
+ .unique()
+ .sorted()
+ .into_iter() // Cannot sort toml::Value, hence uglyness here
+ .map(|link| link.to_value().context(EM::ConversionError).map_err(Error::from))
+ .collect()
+ }
+}
+
+/// An Iterator that `Store::get()`s the Entries from the store while consumed
+pub struct GetIter<'a>(IntoIter<Link>, &'a Store);
+
+impl<'a> GetIter<'a> {
+ pub fn new(i: IntoIter<Link>, store: &'a Store) -> GetIter<'a> {
+ GetIter(i, store)
+ }
+
+ pub fn store(&self) -> &Store {
+ self.1
+ }
+}
+
+impl<'a> Iterator for GetIter<'a> {
+ type Item = Result<FileLockEntry<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().and_then(|id| match self.1.get(id) {
+ Ok(None) => None,
+ Ok(Some(x)) => Some(Ok(x)),
+ Err(e) => Some(Err(e).map_err(From::from)),
+ })
+ }
+
+}
+
diff --git a/lib/entry/libimagentrylink/src/lib.rs b/lib/entry/libimagentrylink/src/lib.rs
index 992d3dd2..84fcba78 100644
--- a/lib/entry/libimagentrylink/src/lib.rs
+++ b/lib/entry/libimagentrylink/src/lib.rs
@@ -56,5 +56,8 @@ extern crate libimagutil;
module_entry_path_mod!("links");
-pub mod internal;
+pub mod iter;
+pub mod linker;
+pub mod link;
+pub mod storecheck;
diff --git a/lib/entry/libimagentrylink/src/link.rs b/lib/entry/libimagentrylink/src/link.rs
new file mode 100644
index 00000000..eb594877
--- /dev/null
+++ b/lib/entry/libimagentrylink/src/link.rs
@@ -0,0 +1,150 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+use libimagstore::storeid::StoreId;
+use libimagstore::storeid::IntoStoreId;
+use libimagstore::store::Store;
+use libimagerror::errors::ErrorMsg as EM;
+
+use toml::Value;
+use toml::map::Map;
+use failure::ResultExt;
+use failure::Fallible as Result;
+use failure::Error;
+
+#[derive(Eq, PartialOrd, Ord, Hash, Debug, Clone)]
+pub enum Link {
+ Id { link: StoreId },
+ Annotated { link: StoreId, annotation: String },
+}
+
+impl Link {
+
+ pub fn exists(&self, store: &Store) -> Result<bool> {
+ match *self {
+ Link::Id { ref link } => store.exists(link.clone()),
+ Link::Annotated { ref link, .. } => store.exists(link.clone()),
+ }
+ .map_err(From::from)
+ }
+
+ pub fn to_str(&self) -> Result<String> {
+ match *self {
+ Link::Id { ref link } => link.to_str(),
+ Link::Annotated { ref link, .. } => link.to_str(),
+ }
+ .map_err(From::from)
+ }
+
+
+ pub(crate) fn eq_store_id(&self, id: &StoreId) -> bool {
+ match self {
+ &Link::Id { link: ref s } => s.eq(id),
+ &Link::Annotated { link: ref s, .. } => s.eq(id),
+ }
+ }
+
+ /// Get the StoreId inside the Link, which is always present
+ pub fn get_store_id(&self) -> &StoreId {
+ match self {
+ &Link::Id { link: ref s } => s,
+ &Link::Annotated { link: ref s, .. } => s,
+ }
+ }
+
+ /// Helper wrapper around Link for StoreId
+ pub(crate) fn without_base(self) -> Link {
+ match self {
+ Link::Id { link: s } => Link::Id { link: s },
+ Link::Annotated { link: s, annotation: ann } =>
+ Link::Annotated { link: s, annotation: ann },
+ }
+ }
+
+ pub(crate) fn to_value(&self) -> Result<Value> {
+ match self {
+ &Link::Id { link: ref s } =>
+ s.to_str()
+ .map(Value::String)
+ .context(EM::ConversionError)
+ .map_err(Error::from),
+ &Link::Annotated { ref link, annotation: ref anno } => {
+ link.to_str()
+ .map(Value::String)
+ .context(EM::ConversionError)
+ .map_err(Error::from)
+ .map(|link| {
+ let mut tab = Map::new();
+
+ tab.insert("link".to_owned(), link);
+ tab.insert("annotation".to_owned(), Value::String(anno.clone()));
+ Value::Table(tab)
+ })
+ }
+ }
+ }
+
+}
+
+impl ::std::cmp::PartialEq for Link {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (&Link::Id { link: ref a }, &Link::Id { link: ref b }) => a.eq(&b),
+ (&Link::Annotated { link: ref a, annotation: ref ann1 },
+ &Link::Annotated { link: ref b, annotation: ref ann2 }) =>
+ (a, ann1).eq(&(b, ann2)),
+ _ => false,
+ }
+ }
+}
+
+impl From<StoreId> for Link {
+
+ fn from(s: StoreId) -> Link {
+ Link::Id { link: s }
+ }
+}
+
+impl Into<StoreId> for Link {
+ fn into(self) -> StoreId {
+ match self {
+ Link::Id { link } => link,
+ Link::Annotated { link, .. } => link,
+ }
+ }
+}
+
+impl IntoStoreId for Link {
+ fn into_storeid(self) -> Result<StoreId> {
+ match self {
+ Link::Id { link } => Ok(link),
+ Link::Annotated { link, .. } => Ok(link),
+ }
+ }
+}
+
+impl AsRef<StoreId> for Link {
+ fn as_ref(&self) -> &StoreId {
+ match self {
+ &Link::Id { ref link } => &link,
+ &Link::Annotated { ref link, .. } => &link,
+ }
+ }
+}
+
diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/linker.rs
index ca24201f..a94a5707 100644
--- a/lib/entry/libimagentrylink/src/internal.rs
+++ b/lib/entry/libimagentrylink/src/linker.rs
@@ -18,144 +18,23 @@
//
use libimagstore::storeid::StoreId;
-use libimagstore::storeid::IntoStoreId;
use libimagstore::store::Entry;
use libimagstore::store::Store;
use libimagerror::errors::ErrorMsg as EM;
use toml_query::read::TomlValueReadExt;
use toml_query::insert::TomlValueInsertExt;
-use toml::map::Map;
use failure::ResultExt;
use failure::Fallible as Result;
use failure::Error;
use failure::err_msg;
-use self::iter::LinkIter;
-use self::iter::IntoValues;
+use crate::iter::LinkIter;
+use crate::iter::IntoValues;
+use crate::link::Link;
use toml::Value;
-#[derive(Eq, PartialOrd, Ord, Hash, Debug, Clone)]
-pub enum Link {
- Id { link: StoreId },
- Annotated { link: StoreId, annotation: String },
-}
-
-impl Link {
-
- pub fn exists(&self, store: &Store) -> Result<bool> {
- match *self {
- Link::Id { ref link } => store.exists(link.clone()),
- Link::Annotated { ref link, .. } => store.exists(link.clone()),
- }
- .map_err(From::from)
- }
-
- pub fn to_str(&self) -> Result<String> {
- match *self {
- Link::Id { ref link } => link.to_str(),
- Link::Annotated { ref link, .. } => link.to_str(),
- }
- .map_err(From::from)
- }
-
-
- fn eq_store_id(&self, id: &StoreId) -> bool {
- match self {
- &Link::Id { link: ref s } => s.eq(id),
- &Link::Annotated { link: ref s, .. } => s.eq(id),
- }
- }
-
- /// Get the StoreId inside the Link, which is always present
- pub fn get_store_id(&self) -> &StoreId {
- match self {
- &Link::Id { link: ref s } => s,
- &Link::Annotated { link: ref s, .. } => s,
- }
- }
-
- /// Helper wrapper around Link for StoreId
- fn without_base(self) -> Link {
- match self {
- Link::Id { link: s } => Link::Id { link: s },
- Link::Annotated { link: s, annotation: ann } =>
- Link::Annotated { link: s, annotation: ann },
- }
- }
-
- fn to_value(&self) -> Result<Value> {
- match self {
- &Link::Id { link: ref s } =>
- s.to_str()
- .map(Value::String)
- .context(EM::ConversionError)
- .map_err(Error::from),
- &Link::Annotated { ref link, annotation: ref anno } => {
- link.to_str()
- .map(Value::String)
- .context(EM::ConversionError)
- .map_err(Error::from)
- .map(|link| {
- let mut tab = Map::new();
-
- tab.insert("link".to_owned(), link);
- tab.insert("annotation".to_owned(), Value::String(anno.clone()));
- Value::Table(tab)
- })
- }
- }
- }
-
-}
-
-impl ::std::cmp::PartialEq for Link {
- fn eq(&self, other: &Self) -> bool {
- match (self, other) {
- (&Link::Id { link: ref a }, &Link::Id { link: ref b }) => a.eq(&b),
- (&Link::Annotated { link: ref a, annotation: ref ann1 },
- &Link::Annotated { link: ref b, annotation: ref ann2 }) =>
- (a, ann1).eq(&(b, ann2)),
- _ => false,
- }
- }
-}
-
-impl From<StoreId> for Link {
-
- fn from(s: StoreId) -> Link {
- Link::Id { link: s }
- }
-}
-
-impl Into<StoreId> for Link {
- fn into(self) -> StoreId {
- match self {
- Link::Id { link } => link,
- Link::Annotated { link, .. } => link,
- }
- }
-}
-
-impl IntoStoreId for Link {
- fn into_storeid(self) -> Result<StoreId> {
- match self {
- Link::Id { link } => Ok(link),
- Link::Annotated { link, .. } => Ok(link),
- }
- }
-}
-
-impl AsRef<StoreId> for Link {
- fn as_ref(&self) -> &StoreId {
- match self {
- &Link::Id { ref link } => &link,
- &Link::Annotated { ref link, .. } => &link,
- }
- }
-}
-
pub trait InternalLinker {
/// Get the internal links from the implementor object
@@ -174,85 +53,6 @@ pub trait InternalLinker {
fn add_internal_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()>;
}
-pub mod iter {
- use std::vec::IntoIter;
- use super::Link;
-
- use failure::Error;
- use failure::Fallible as Result;
- use failure::ResultExt;
- use toml::Value;
- use itertools::Itertools;
-
- use libimagstore::store::Store;
- use libimagstore::store::FileLockEntry;
- use libimagerror::errors::ErrorMsg as EM;
-
- pub struct LinkIter(IntoIter<Link>);
-
- impl LinkIter {
-
- pub fn new(v: Vec<Link>) -> LinkIter {
- LinkIter(v.into_iter())
- }
-
- pub fn into_getter(self, store: &Store) -> GetIter {
- GetIter(self.0, store)
- }
-
- }
-
- impl Iterator for LinkIter {
- type Item = Link;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next()
- }
- }
-
- pub trait IntoValues {
- fn into_values(self) -> Vec<Result<Value>>;
- }
-
- impl<I: Iterator<Item = Link>> IntoValues for I {
- fn into_values(self) -> Vec<Result<Value>> {
- self.map(|s| s.without_base())
- .unique()
- .sorted()
- .into_iter() // Cannot sort toml::Value, hence uglyness here
- .map(|link| link.to_value().context(EM::ConversionError).map_err(Error::from))
- .collect()
- }
- }
-
- /// An Iterator that `Store::get()`s the Entries from the store while consumed
- pub struct GetIter<'a>(IntoIter<Link>, &'a Store);
-
- impl<'a> GetIter<'a> {
- pub fn new(i: IntoIter<Link>, store: &'a Store) -> GetIter<'a> {
- GetIter(i, store)
- }
-
- pub fn store(&self) -> &Store {
- self.1
- }
- }
-
- impl<'a> Iterator for GetIter<'a> {
- type Item = Result<FileLockEntry<'a>>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next().and_then(|id| match self.1.get(id) {
- Ok(None) => None,
- Ok(Some(x)) => Some(Ok(x)),
- Err(e) => Some(Err(e).map_err(From::from)),
- })
- }
-
- }
-
-}
-
impl InternalLinker for Entry {
fn get_internal_links(&self) -> Result<LinkIter> {
@@ -452,164 +252,6 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
Ok(LinkIter::new(links))
}
-pub mod store_check {
- use libimagstore::store::Store;
-
- use failure::ResultExt;
- use failure::Fallible as Result;
- use failure::Error;
- use failure::err_msg;
-
- pub trait StoreLinkConsistentExt {
- fn check_link_consistency(&self) -> Result<()>;
- }
-
- impl StoreLinkConsistentExt for Store {
- fn check_link_consistency(&self) -> Result<()> {
- use std::collections::HashMap;
-
- use crate::internal::InternalLinker;
-
- use libimagstore::storeid::StoreId;
- use libimagutil::debug_result::DebugResult;
-
- // Helper data structure to collect incoming and outgoing links for each StoreId
- #[derive(Debug, Default)]
- struct Linking {
- outgoing: Vec<StoreId>,
- incoming: Vec<StoreId>,
- }
-
- // Helper function to aggregate the Link network
- //
- // This function aggregates a HashMap which maps each StoreId object in the store onto
- // a Linking object, which contains a list of StoreIds which this entry links to and a
- // list of StoreIds which link to the current one.
- //
- // The lambda returns an error if something fails
- let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> {
- store
- .entries()?
- .into_get_iter()
- .fold(Ok(HashMap::new()), |map, element| {
- map.and_then(|mut map| {
- debug!("Checking element = {:?}", element);
- let entry = element?.ok_or_else(|| err_msg("TODO: Not yet handled"))?;
-
- debug!("Checking entry = {:?}", entry.get_location());
-
- let internal_links = entry
- .get_internal_links()?
- .into_getter(store); // get the FLEs from the Store
-
- let mut linking = Linking::default();
- for internal_link in internal_links {
- debug!("internal link = {:?}", internal_link);
-
- linking.outgoing.push(internal_link?.get_location().clone());
- linking.incoming.push(entry.get_location().clone());
- }
-
- map.insert(entry.get_location().clone(), linking);
- Ok(map)
- })
- })
- };
-
- // Helper to check whethre all StoreIds in the network actually exists
- //
- // Because why not?
- let all_collected_storeids_exist = |network: &HashMap<StoreId, Linking>| -> Result<()> {
- for (id, _) in network.iter() {
- if is_match!(self.get(id.clone()), Ok(Some(_))) {
- debug!("Exists in store: {:?}", id);
-
- if !self.exists(id.clone())? {
- warn!("Does exist in store but not on FS: {:?}", id);
- return Err(err_msg("Link target does not exist"))
- }
- } else {
- warn!("Does not exist in store: {:?}", id);
- return Err(err_msg("Link target does not exist"))
- }
- }
-
- Ok(())
- };
-
- // Helper function to create a SLCECD::OneDirectionalLink error object
- let mk_one_directional_link_err = |src: StoreId, target: StoreId| -> Error {
- Error::from(format_err!("Dead link: {} -> {}",
- src.local_display_string(),
- target.local_display_string()))
- };
-
- // Helper lambda to check whether the _incoming_ links of each entry actually also
- // appear in the _outgoing_ list of the linked entry
- let incoming_links_exists_as_outgoing_links =
- |src: &StoreId, linking: &Linking, network: &HashMap<StoreId, Linking>| -> Result<()> {
- for link in linking.incoming.iter() {
- // Check whether the links which are _incoming_ on _src_ are outgoing
- // in each of the links in the incoming list.
- let incoming_consistent = network.get(link)
- .map(|l| l.outgoing.contains(src))
- .unwrap_or(false);
-
- if !incoming_consistent {
- return Err(mk_one_directional_link_err(src.clone(), link.clone()))
- }
- }
-
- Ok(())
- };
-
- // Helper lambda to check whether the _outgoing links of each entry actually also
- // appear in the _incoming_ list of the linked entry
- let outgoing_links_exist_as_incoming_links =
- |src: &StoreId, linking: &Linking, network: &HashMap<StoreId, Linking>| -> Result<()> {
- for link in linking.outgoing.iter() {
- // Check whether the links which are _outgoing_ on _src_ are incoming
- // in each of the links in the outgoing list.
- let outgoing_consistent = network.get(link)
- .map(|l| l.incoming.contains(src))
- .unwrap_or(false);
-
- if !outgoing_consistent {
- return Err(mk_one_directional_link_err(link.clone(), src.clone()))
- }
- }
-
- Ok(())
- };
-
- aggregate_link_network(&self)
- .map_dbg_str("Aggregated")
- .map_dbg(|nw| {
- let mut s = String::new();
- for (k, v) in nw {
-