diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2019-05-30 17:54:48 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2019-05-31 12:48:00 +0200 |
commit | 901502b67efd885b2deb9ff1346808689e025f4c (patch) | |
tree | c5f1bda7d9af1f774bd54d9d3e34b93e713195e2 | |
parent | d02d53594e8b95786f4cff93aab3c87132889bf3 (diff) |
Split "internal" module into several submodules
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
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 { - |