~matthiasbeyer/imag

fd59d6d3017b38083e65bd447c4c09b04ae8ae3b — Matthias Beyer 2 years ago f21b6e5 + 5dc6829
Merge branch 'libimagentrylink-interface-redesign' into master
M bin/core/imag-annotate/src/main.rs => bin/core/imag-annotate/src/main.rs +2 -2
@@ 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::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;

mod ui;



@@ 124,7 124,7 @@ fn add(rt: &Runtime) {
                .ok_or_else(|| format_err!("Not found: {}", id.local_display_string()))
                .map_err_trace_exit_unwrap();

            let _ = entry.add_internal_link(&mut annotation).map_err_trace_exit_unwrap();
            let _ = entry.add_link(&mut annotation).map_err_trace_exit_unwrap();
        }

        if !scmd.is_present("dont-print-name") {

M bin/core/imag-diagnostics/src/main.rs => bin/core/imag-diagnostics/src/main.rs +13 -13
@@ 55,7 55,7 @@ use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;

use toml::Value;
use toml_query::read::TomlValueReadExt;


@@ 76,7 76,7 @@ struct Diagnostic {
    pub bytecount_content: usize,
    pub overall_byte_size: usize,
    pub verified: bool,
    pub num_internal_links: usize,
    pub num_links: usize,
}

impl Diagnostic {


@@ 100,7 100,7 @@ impl Diagnostic {
            bytecount_content: entry.get_content().as_str().len(),
            overall_byte_size: entry.to_str()?.as_str().len(),
            verified: entry.verify().is_ok(),
            num_internal_links: entry.get_internal_links().map(Iterator::count).unwrap_or(0),
            num_links: entry.links().map(Iterator::count).unwrap_or(0),
        })
    }
}


@@ 176,15 176,15 @@ fn main() {
    let mut max_overall_byte_size : Option<(usize, StoreId)> = None;
    let mut verified_count        = 0;
    let mut unverified_count      = 0;
    let mut num_internal_links    = 0;
    let mut max_internal_links : Option<(usize, StoreId)> = None;
    let mut num_links    = 0;
    let mut max_links : Option<(usize, StoreId)> = None;

    for diag in diags.iter() {
        sum_header_sections     += diag.header_sections;
        sum_bytecount_content   += diag.bytecount_content;
        sum_overall_byte_size   += diag.overall_byte_size;
        match max_overall_byte_size {
            None => max_overall_byte_size = Some((diag.num_internal_links, diag.id.clone())),
            None => max_overall_byte_size = Some((diag.num_links, diag.id.clone())),
            Some((num, _)) => if num < diag.overall_byte_size {
                max_overall_byte_size = Some((diag.overall_byte_size, diag.id.clone()));
            }


@@ 199,11 199,11 @@ fn main() {
            unverified_count += 1;
        }

        num_internal_links += diag.num_internal_links;
        match max_internal_links {
            None => max_internal_links = Some((diag.num_internal_links, diag.id.clone())),
            Some((num, _)) => if num < diag.num_internal_links {
                max_internal_links = Some((diag.num_internal_links, diag.id.clone()));
        num_links += diag.num_links;
        match max_links {
            None => max_links = Some((diag.num_links, diag.id.clone())),
            Some((num, _)) => if num < diag.num_links {
                max_links = Some((diag.num_links, diag.id.clone()));
            }
        }



@@ 230,9 230,9 @@ fn main() {
            do_write!(out, "Largest Entry ({} bytes): {}", num, path.local_display_string());
        }

        do_write!(out, "{} average internal link count per entry", num_internal_links / n);
        do_write!(out, "{} average internal link count per entry", num_links / n);

        if let Some((num, path)) = max_internal_links {
        if let Some((num, path)) = max_links {
            do_write!(out, "Entry with most internal links ({}): {}",
                     num,
                     path.local_display_string());

M bin/core/imag-link/src/main.rs => bin/core/imag-link/src/main.rs +4 -4
@@ 63,7 63,7 @@ use failure::Error;
use failure::err_msg;

use libimagentryurl::linker::UrlLinker;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagentrylink::storecheck::StoreLinkConsistentExt;
use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::exit::ExitUnwrap;


@@ 182,7 182,7 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)
                },
            };
            let _ = from_entry
                .add_internal_link(&mut to_entry)
                .add_link(&mut to_entry)
                .map_err_trace_exit_unwrap();

            let _ = rt.report_touched(to_entry.get_location()).unwrap_or_exit();


@@ 222,7 222,7 @@ fn remove_linking(rt: &Runtime) {
            Err(e) => trace_error(&e),
            Ok(Some(mut to_entry)) => {
                let _ = to_entry
                    .remove_internal_link(&mut from)
                    .remove_link(&mut from)
                    .map_err_trace_exit_unwrap();

                let _ = rt.report_touched(to_entry.get_location()).unwrap_or_exit();


@@ 296,7 296,7 @@ fn list_linkings(rt: &Runtime) {
        .for_each(|id| {
            match rt.store().get(id.clone()) {
                Ok(Some(entry)) => {
                    for (i, link) in entry.get_internal_links().map_err_trace_exit_unwrap().enumerate() {
                    for (i, link) in entry.links().map_err_trace_exit_unwrap().enumerate() {
                        let link = link
                            .to_str()
                            .map_warn_err(|e| format!("Failed to convert StoreId to string: {:?}", e))

M bin/core/imag-mv/src/main.rs => bin/core/imag-mv/src/main.rs +4 -4
@@ 56,7 56,7 @@ use libimagerror::exit::ExitUnwrap;
use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagstore::iter::get::StoreIdGetIteratorExtension;

fn main() {


@@ 93,7 93,7 @@ fn main() {
                error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
                exit(1)
            })
            .get_internal_links()
            .links()
            .map_err_trace_exit_unwrap()
            .map(|link| Ok(link.get_store_id().clone()) as Result<_, _>)
            .into_get_iter(rt.store())


@@ 118,7 118,7 @@ fn main() {
            });

        for link in linked_entries.iter_mut() {
            let _ = entry.remove_internal_link(link).map_err_trace_exit_unwrap();
            let _ = entry.remove_link(link).map_err_trace_exit_unwrap();
        }
    }



@@ 151,6 151,6 @@ fn relink<'a>(store: &'a Store, target: StoreId, linked_entries: &mut Vec<FileLo


    for mut link in linked_entries {
        let _ = entry.add_internal_link(&mut link).map_err_trace_exit_unwrap();
        let _ = entry.add_link(&mut link).map_err_trace_exit_unwrap();
    }
}

M bin/domain/imag-bookmark/src/main.rs => bin/domain/imag-bookmark/src/main.rs +5 -6
@@ 48,6 48,7 @@ extern crate libimagentrylink;

use std::io::Write;
use std::process::exit;
use std::ops::DerefMut;

use toml_query::read::TomlValueReadTypeExt;
use failure::Error;


@@ 61,7 62,7 @@ use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagutil::debug_result::DebugResult;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;


mod ui;


@@ 107,8 108,7 @@ fn add(rt: &Runtime) {
    let _ = rt.report_touched(collection.get_location()).unwrap_or_exit();

    for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
        let new_ids = collection
            .add_link(rt.store(), BookmarkLink::from(url))
        let new_ids = BookmarkCollection::add_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
            .map_err_trace_exit_unwrap();

        let _ = rt.report_all_touched(new_ids.into_iter()).unwrap_or_exit();


@@ 163,7 163,7 @@ fn list(rt: &Runtime) {
    let _ = rt.report_touched(collection.get_location()).unwrap_or_exit();

    collection
        .links(rt.store())
        .get_links(rt.store())
        .map_dbg_str("Listing...")
        .map_err_trace_exit_unwrap()
        .into_iter()


@@ 187,8 187,7 @@ fn remove(rt: &Runtime) {
    let _ = rt.report_touched(collection.get_location()).unwrap_or_exit();

    for url in scmd.values_of("urls").unwrap() { // enforced by clap
        let removed_links = collection
            .remove_link(rt.store(), BookmarkLink::from(url))
        let removed_links = BookmarkCollection::remove_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
            .map_err_trace_exit_unwrap();

        let _ = rt.report_all_touched(removed_links.into_iter()).unwrap_or_exit();

M bin/domain/imag-wiki/src/main.rs => bin/domain/imag-wiki/src/main.rs +1 -1
@@ 252,7 252,7 @@ fn show(rt: &Runtime, wiki_name: &str) {
}

fn delete(rt: &Runtime, wiki_name: &str) {
    use libimagentrylink::linker::InternalLinker;
    use libimagentrylink::linkable::Linkable;

    let scmd   = rt.cli().subcommand_matches("delete").unwrap(); // safed by clap
    let name   = String::from(scmd.value_of("delete-name").unwrap()); // safe by clap

M lib/domain/libimagbookmark/src/collection.rs => lib/domain/libimagbookmark/src/collection.rs +5 -5
@@ 36,7 36,7 @@ use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagentryurl::linker::UrlLinker;
use libimagentryurl::iter::UrlIter;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagentrylink::link::Link as StoreLink;

use crate::link::Link;


@@ 80,8 80,8 @@ impl<'a> BookmarkCollectionStore<'a> for Store {

}

pub trait BookmarkCollection : Sized + InternalLinker + UrlLinker {
    fn links<'a>(&self, store: &'a Store)                        -> Result<UrlIter<'a>>;
pub trait BookmarkCollection : Sized + Linkable + UrlLinker {
    fn get_links<'a>(&self, store: &'a Store)                    -> Result<UrlIter<'a>>;
    fn link_entries(&self)                                       -> Result<Vec<StoreLink>>;
    fn add_link(&mut self, store: &Store, l: Link)               -> Result<Vec<StoreId>>;
    fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result<LinksMatchingRegexIter<'a>>;


@@ 90,13 90,13 @@ pub trait BookmarkCollection : Sized + InternalLinker + UrlLinker {

impl BookmarkCollection for Entry {

    fn links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>> {
    fn get_links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>> {
        self.get_urls(store)
    }

    fn link_entries(&self) -> Result<Vec<StoreLink>> {
        use libimagentryurl::util::is_external_link_storeid;
        self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
        self.links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
    }

    fn add_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>> {

M lib/domain/libimaghabit/src/habit.rs => lib/domain/libimaghabit/src/habit.rs +4 -4
@@ 33,7 33,7 @@ use crate::util::IsHabitCheck;
use crate::util::get_string_header_from_entry;
use crate::instance::IsHabitInstance;

use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;


@@ 129,7 129,7 @@ impl HabitTemplate for Entry {

    fn linked_instances(&self) -> Result<HabitInstanceStoreIdIterator> {
        let iter = self
            .get_internal_links()?
            .links()?
            .map(|link| link.get_store_id().clone())
            .filter(IsHabitCheck::is_habit_instance)
            .map(Ok);


@@ 239,7 239,7 @@ impl HabitTemplate for Entry {
        let name = self.habit_name()?;
        let date = date_to_string(date);

        for link in self.get_internal_links()? {
        for link in self.links()? {
            let sid         = link.get_store_id();
            let instance_id = instance_id_for_name_and_datestr(&name, &date)?;



@@ 410,7 410,7 @@ fn postprocess_instance<'a>(mut entry: FileLockEntry<'a>,
        let _   = hdr.insert("habit.instance.comment", Value::String(comment))?;
    }

    entry.add_internal_link(template)?;
    entry.add_link(template)?;

    Ok(entry)
}

M lib/domain/libimagwiki/src/entry.rs => lib/domain/libimagwiki/src/entry.rs +2 -2
@@ 55,8 55,8 @@ impl WikiEntry for Entry {
    ///
    fn autolink(&mut self, store: &Store) -> Result<()> {
        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(true)
            .process_links(true)
            .create_targets(true)
            .process_urls(true)
            .process_refs(true);


M lib/domain/libimagwiki/src/wiki.rs => lib/domain/libimagwiki/src/wiki.rs +3 -3
@@ 22,7 22,7 @@ use std::path::PathBuf;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagstore::iter::Entries;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;

use failure::Fallible as Result;
use failure::Error;


@@ 78,7 78,7 @@ impl<'a, 'b> Wiki<'a, 'b> {
            .ok_or_else(|| err_msg("Missing index page"))?;
        let mut entry = self.0.create(sid)?;

        entry.add_internal_link(&mut index).map(|_| entry)
        entry.add_link(&mut index).map(|_| entry)
    }

    pub fn retrieve_entry<EN: AsRef<str>>(&self, entry_name: EN) -> Result<FileLockEntry<'a>> {


@@ 89,7 89,7 @@ impl<'a, 'b> Wiki<'a, 'b> {
            .ok_or_else(|| err_msg("Missing index page"))?;
        let mut entry = self.0.retrieve(sid)?;

        entry.add_internal_link(&mut index).map(|_| entry)
        entry.add_link(&mut index).map(|_| entry)
    }

    pub fn all_ids(&self) -> Result<Entries<'a>> {

M lib/entry/libimagentryannotation/src/annotateable.rs => lib/entry/libimagentryannotation/src/annotateable.rs +4 -4
@@ 24,7 24,7 @@ use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagentryutil::isa::Is;
use libimagentryutil::isa::IsKindHeaderPathProvider;



@@ 62,7 62,7 @@ impl Annotateable for Entry {
                Ok(anno)
            })
            .and_then(|mut anno| {
                anno.add_internal_link(self)
                anno.add_link(self)
                    .context(err_msg("Linking error"))
                    .map_err(Error::from)
                    .map(|_| anno)


@@ 74,7 74,7 @@ impl Annotateable for Entry {
    // exist.
    fn denotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<Option<FileLockEntry<'a>>> {
        if let Some(mut annotation) = store.get(crate::module_path::new_id(ann_name)?)? {
            let _ = self.remove_internal_link(&mut annotation)?;
            let _ = self.remove_link(&mut annotation)?;
            Ok(Some(annotation))
        } else {
            // error: annotation does not exist


@@ 84,7 84,7 @@ impl Annotateable for Entry {

    /// Get all annotations of an entry
    fn annotations(&self) -> Result<StoreIdIterator> {
        self.get_internal_links()
        self.links()
            .map(|it| {
                it.filter(|link| link.get_store_id().is_in_collection(&["annotation"]))
                    .map(|link| Ok(link.get_store_id().clone()))

M lib/entry/libimagentrycategory/src/category.rs => lib/entry/libimagentrycategory/src/category.rs +2 -2
@@ 22,7 22,7 @@ use libimagentryutil::isa::IsKindHeaderPathProvider;
use libimagstore::store::Entry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreIdIterator;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;

use toml_query::read::TomlValueReadTypeExt;



@@ 57,7 57,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()).map(Ok);
        let sit  = self.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))

M lib/entry/libimagentrycategory/src/entry.rs => lib/entry/libimagentrycategory/src/entry.rs +2 -2
@@ 23,7 23,7 @@ use toml_query::read::TomlValueReadTypeExt;
use toml::Value;

use libimagstore::store::Entry;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagerror::errors::ErrorMsg as EM;

use failure::Fallible as Result;


@@ 68,7 68,7 @@ impl EntryCategory for Entry {
            .ok_or_else(|| Error::from(err_msg("Category does not exist")))?;

        let _ = self.set_category(s)?;
        let _ = self.add_internal_link(&mut category)?;
        let _ = self.add_link(&mut category)?;

        Ok(())
    }

M lib/entry/libimagentrycategory/src/store.rs => lib/entry/libimagentrycategory/src/store.rs +2 -2
@@ 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::linker::InternalLinker;
        use libimagentrylink::linkable::Linkable;
        use crate::category::Category;

        trace!("Deleting category: '{}'", name);


@@ 97,7 97,7 @@ impl CategoryStore for Store {

            for entry in category.get_entries(self)? {
                let mut entry = entry?;
                let _         = category.remove_internal_link(&mut entry)?;
                let _         = category.remove_link(&mut entry)?;
            }
        }


M lib/entry/libimagentrylink/src/lib.rs => lib/entry/libimagentrylink/src/lib.rs +1 -1
@@ 57,7 57,7 @@ extern crate libimagutil;
module_entry_path_mod!("links");

pub mod iter;
pub mod linker;
pub mod linkable;
pub mod link;
pub mod storecheck;


R lib/entry/libimagentrylink/src/linker.rs => lib/entry/libimagentrylink/src/linkable.rs +112 -112
@@ 35,27 35,27 @@ use crate::link::Link;

use toml::Value;

pub trait InternalLinker {
pub trait Linkable {

    /// Get the internal links from the implementor object
    fn get_internal_links(&self) -> Result<LinkIter>;
    fn links(&self) -> Result<LinkIter>;

    /// Add an internal link to the implementor object
    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()>;
    fn add_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove an internal link from the implementor object
    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>;
    fn remove_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove _all_ internal links
    fn unlink(&mut self, store: &Store) -> Result<()>;

    /// Add internal annotated link
    fn add_internal_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()>;
    fn add_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()>;
}

impl InternalLinker for Entry {
impl Linkable for Entry {

    fn get_internal_links(&self) -> Result<LinkIter> {
    fn links(&self) -> Result<LinkIter> {
        debug!("Getting internal links");
        trace!("Getting internal links from header of '{}' = {:?}", self.get_location(), self.get_header());
        let res = self


@@ 69,13 69,13 @@ impl InternalLinker for Entry {
        process_rw_result(res)
    }

    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> {
    fn add_link(&mut self, link: &mut Entry) -> Result<()> {
        debug!("Adding internal link: {:?}", link);
        let location = link.get_location().clone().into();
        add_internal_link_with_instance(self, link, location)
        add_link_with_instance(self, link, location)
    }

    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> {
    fn remove_link(&mut self, link: &mut Entry) -> Result<()> {
        debug!("Removing internal link: {:?}", link);

        // Cloning because of borrowing


@@ 84,13 84,13 @@ impl InternalLinker for Entry {

        debug!("Removing internal link from {:?} to {:?}", own_loc, other_loc);

        let links = link.get_internal_links()?;
        let links = link.links()?;
        debug!("Rewriting own links for {:?}, without {:?}", other_loc, own_loc);

        let links = links.filter(|l| !l.eq_store_id(&own_loc));
        let _     = rewrite_links(link.get_header_mut(), links)?;

        self.get_internal_links()
        self.links()
            .and_then(|links| {
                debug!("Rewriting own links for {:?}, without {:?}", own_loc, other_loc);
                let links = links.filter(|l| !l.eq_store_id(&other_loc));


@@ 99,9 99,9 @@ impl InternalLinker for Entry {
    }

    fn unlink(&mut self, store: &Store) -> Result<()> {
        for id in self.get_internal_links()?.map(|l| l.get_store_id().clone()) {
        for id in self.links()?.map(|l| l.get_store_id().clone()) {
            match store.get(id).context("Failed to get entry")? {
                Some(mut entry) => self.remove_internal_link(&mut entry)?,
                Some(mut entry) => self.remove_link(&mut entry)?,
                None            => return Err(err_msg("Link target does not exist")),
            }
        }


@@ 109,23 109,23 @@ impl InternalLinker for Entry {
        Ok(())
    }

    fn add_internal_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()> {
    fn add_annotated_link(&mut self, link: &mut Entry, annotation: String) -> Result<()> {
        let new_link = Link::Annotated {
            link: link.get_location().clone(),
            annotation: annotation,
        };

        add_internal_link_with_instance(self, link, new_link)
        add_link_with_instance(self, link, new_link)
    }

}

fn add_internal_link_with_instance(this: &mut Entry, link: &mut Entry, instance: Link) -> Result<()> {
fn add_link_with_instance(this: &mut Entry, link: &mut Entry, instance: Link) -> Result<()> {
    debug!("Adding internal link from {:?} to {:?}", this.get_location(), instance);

    add_foreign_link(link, this.get_location().clone())
        .and_then(|_| {
            this.get_internal_links()
            this.links()
                .and_then(|links| {
                    let links = links.chain(LinkIter::new(vec![instance]));
                    rewrite_links(this.get_header_mut(), links)


@@ 156,7 156,7 @@ fn rewrite_links<I: Iterator<Item = Link>>(header: &mut Value, links: I) -> Resu
/// This is a helper function which does this.
fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
    debug!("Linking back from {:?} to {:?}", target.get_location(), from);
    target.get_internal_links()
    target.links()
        .and_then(|links| {
            let links = links
                             .chain(LinkIter::new(vec![from.into()]))


@@ 258,7 258,7 @@ mod test {

    use libimagstore::store::Store;

    use super::InternalLinker;
    use super::Linkable;
    use super::Link;

    fn setup_logging() {


@@ 274,7 274,7 @@ mod test {
        setup_logging();
        let store = get_store();
        let entry = store.create(PathBuf::from("test_new_entry_no_links")).unwrap();
        let links = entry.get_internal_links();
        let links = entry.links();
        assert!(links.is_ok());
        let links = links.unwrap();
        assert_eq!(links.collect::<Vec<_>>().len(), 0);


@@ 285,16 285,16 @@ mod test {
        setup_logging();
        let store = get_store();
        let mut e1 = store.create(PathBuf::from("test_link_two_entries1")).unwrap();
        assert!(e1.get_internal_links().is_ok());
        assert!(e1.links().is_ok());

        let mut e2 = store.create(PathBuf::from("test_link_two_entries2")).unwrap();
        assert!(e2.get_internal_links().is_ok());
        assert!(e2.links().is_ok());

        {
            assert!(e1.add_internal_link(&mut e2).is_ok());
            assert!(e1.add_link(&mut e2).is_ok());

            let e1_links = e1.get_internal_links().unwrap().collect::<Vec<_>>();
            let e2_links = e2.get_internal_links().unwrap().collect::<Vec<_>>();
            let e1_links = e1.links().unwrap().collect::<Vec<_>>();
            let e2_links = e2.links().unwrap().collect::<Vec<_>>();

            debug!("1 has links: {:?}", e1_links);
            debug!("2 has links: {:?}", e2_links);


@@ 307,14 307,14 @@ mod test {
        }

        {
            assert!(e1.remove_internal_link(&mut e2).is_ok());
            assert!(e1.remove_link(&mut e2).is_ok());

            debug!("{:?}", e2.to_str());
            let e2_links = e2.get_internal_links().unwrap().collect::<Vec<_>>();
            let e2_links = e2.links().unwrap().collect::<Vec<_>>();
            assert_eq!(e2_links.len(), 0, "Expected [], got: {:?}", e2_links);

            debug!("{:?}", e1.to_str());
            let e1_links = e1.get_internal_links().unwrap().collect::<Vec<_>>();
            let e1_links = e1.links().unwrap().collect::<Vec<_>>();
            assert_eq!(e1_links.len(), 0, "Expected [], got: {:?}", e1_links);

        }


@@ 331,69 331,69 @@ mod test {
        let mut e4 = store.retrieve(PathBuf::from("4")).unwrap();
        let mut e5 = store.retrieve(PathBuf::from("5")).unwrap();

        assert!(e1.add_internal_link(&mut e2).is_ok());
        assert!(e1.add_link(&mut e2).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e1.add_internal_link(&mut e3).is_ok());
        assert!(e1.add_link(&mut e3).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e1.add_internal_link(&mut e4).is_ok());
        assert!(e1.add_link(&mut e4).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 3);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 3);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e1.add_internal_link(&mut e5).is_ok());
        assert!(e1.add_link(&mut e5).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 4);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 4);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 1);

        assert!(e5.remove_internal_link(&mut e1).is_ok());
        assert!(e5.remove_link(&mut e1).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 3);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 3);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e4.remove_internal_link(&mut e1).is_ok());
        assert!(e4.remove_link(&mut e1).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e3.remove_internal_link(&mut e1).is_ok());
        assert!(e3.remove_link(&mut e1).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e2.remove_internal_link(&mut e1).is_ok());
        assert!(e2.remove_link(&mut e1).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e4.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e5.links().unwrap().collect::<Vec<_>>().len(), 0);

    }



@@ 405,18 405,18 @@ mod test {
        let mut e1 = store.retrieve(PathBuf::from("1")).unwrap();
        let mut e2 = store.retrieve(PathBuf::from("2")).unwrap();

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e1.add_internal_link(&mut e2).is_ok());
        assert!(e1.add_link(&mut e2).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);

        assert!(e1.remove_internal_link(&mut e2).is_ok());
        assert!(e1.remove_link(&mut e2).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 0);
    }

    #[test]


@@ 428,40 428,40 @@ mod test {
        let mut e2 = store.retrieve(PathBuf::from("2")).unwrap();
        let mut e3 = store.retrieve(PathBuf::from("3")).unwrap();

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 0);

        assert!(e1.add_internal_link(&mut e2).is_ok()); // 1-2
        assert!(e1.add_internal_link(&mut e3).is_ok()); // 1-2, 1-3
        assert!(e1.add_link(&mut e2).is_ok()); // 1-2
        assert!(e1.add_link(&mut e3).is_ok()); // 1-2, 1-3

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);

        assert!(e2.add_internal_link(&mut e3).is_ok()); // 1-2, 1-3, 2-3
        assert!(e2.add_link(&mut e3).is_ok()); // 1-2, 1-3, 2-3

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 2);

        assert!(e1.remove_internal_link(&mut e2).is_ok()); // 1-3, 2-3
        assert!(e1.remove_link(&mut e2).is_ok()); // 1-3, 2-3

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 2);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 2);

        assert!(e1.remove_internal_link(&mut e3).is_ok()); // 2-3
        assert!(e1.remove_link(&mut e3).is_ok()); // 2-3

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 1);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 1);

        assert!(e2.remove_internal_link(&mut e3).is_ok());
        assert!(e2.remove_link(&mut e3).is_ok());

        assert_eq!(e1.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.get_internal_links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e1.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e2.links().unwrap().collect::<Vec<_>>().len(), 0);
        assert_eq!(e3.links().unwrap().collect::<Vec<_>>().len(), 0);
    }

    #[test]


@@ 471,11 471,11 @@ mod test {
        let mut entry1 = store.create(PathBuf::from("test_link_annotating-1")).unwrap();
        let mut entry2 = store.create(PathBuf::from("test_link_annotating-2")).unwrap();

        let res = entry1.add_internal_annotated_link(&mut entry2, String::from("annotation"));
        let res = entry1.add_annotated_link(&mut entry2, String::from("annotation"));
        assert!(res.is_ok());

        {
            for link in entry1.get_internal_links().unwrap() {
            for link in entry1.links().unwrap() {
                match link  {
                    Link::Annotated {annotation, ..} => assert_eq!(annotation, "annotation"),
                    _ => assert!(false, "Non-annotated link found"),


@@ 484,7 484,7 @@ mod test {
        }

        {
            for link in entry2.get_internal_links().unwrap() {
            for link in entry2.links().unwrap() {
                match link  {
                    Link::Id {..}        => {},
                    Link::Annotated {..} => assert!(false, "Annotated link found"),

M lib/entry/libimagentrylink/src/storecheck.rs => lib/entry/libimagentrylink/src/storecheck.rs +2 -2
@@ 28,7 28,7 @@ use failure::Fallible as Result;
use failure::Error;
use failure::err_msg;

use crate::linker::*;
use crate::linkable::*;

pub trait StoreLinkConsistentExt {
    fn check_link_consistency(&self) -> Result<()>;


@@ 62,7 62,7 @@ impl StoreLinkConsistentExt for Store {
                        debug!("Checking entry = {:?}", entry.get_location());

                        let internal_links = entry
                            .get_internal_links()?
                            .links()?
                            .into_getter(store); // get the FLEs from the Store

                        let mut linking = Linking::default();

M lib/entry/libimagentrymarkdown/src/processor.rs => lib/entry/libimagentrymarkdown/src/processor.rs +42 -42
@@ 25,7 25,7 @@ use failure::Error;
use crate::link::extract_links;

use libimagentryurl::linker::UrlLinker;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;
use libimagentryref::reference::MutRef;
use libimagentryref::reference::RefFassade;
use libimagentryref::hasher::sha1::Sha1Hasher;


@@ 56,8 56,8 @@ use url::Url;
///  There's no LinkProcessor::new() function, please use `LinkProcessor::default()`.
///
pub struct LinkProcessor {
    process_internal_links: bool,
    create_internal_targets: bool,
    process_links: bool,
    create_targets: bool,
    process_urls: bool,
    process_refs: bool
}


@@ 68,8 68,8 @@ impl LinkProcessor {
    ///
    /// Internal links are links which are simply `dirctory/file`, but not `/directory/file`, as
    /// beginning an id with `/` is discouraged in imag.
    pub fn process_internal_links(mut self, b: bool) -> Self {
        self.process_internal_links = b;
    pub fn process_links(mut self, b: bool) -> Self {
        self.process_links = b;
        self
    }



@@ 78,8 78,8 @@ impl LinkProcessor {
    /// If a link points to a non-existing imag entry, a `false` here will cause the processor to
    /// return an error from `process()`. A `true` setting will create the entry and then fetch it
    /// to link it to the processed entry.
    pub fn create_internal_targets(mut self, b: bool) -> Self {
        self.create_internal_targets = b;
    pub fn create_targets(mut self, b: bool) -> Self {
        self.create_targets = b;
        self
    }



@@ 121,14 121,14 @@ impl LinkProcessor {
    ///
    /// # Warning
    ///
    /// When `LinkProcessor::create_internal_targets()` was called to set the setting to true, this
    /// When `LinkProcessor::create_targets()` was called to set the setting to true, this
    /// function returns all errors returned by the Store.
    ///
    /// That means:
    ///
    /// * For an internal link, the linked target is created if create_internal_targets() is true,
    /// * For an internal link, the linked target is created if create_targets() is true,
    ///   else error
    /// * For an external link, if create_internal_targets() is true, libimagentrylink creates the
    /// * For an external link, if create_targets() is true, libimagentrylink creates the
    ///   external link entry, else the link is ignored
    /// * all other cases do not create elements in the store
    ///


@@ 139,19 139,19 @@ impl LinkProcessor {
            trace!("Processing {:?}", link);
            match LinkQualification::qualify(&link.link) {
                LinkQualification::InternalLink => {
                    if !self.process_internal_links {
                    if !self.process_links {
                        continue
                    }

                    let id         = StoreId::new(PathBuf::from(&link.link))?;
                    let mut target = if self.create_internal_targets {
                    let mut target = if self.create_targets {
                        store.retrieve(id)?
                    } else {
                        store.get(id.clone())?
                            .ok_or_else(|| Error::from(format_err!("Store get error: {}", id)))?
                    };

                    let _ = entry.add_internal_link(&mut target)?;
                    let _ = entry.add_link(&mut target)?;
                },
                LinkQualification::ExternalLink(url) => {
                    if !self.process_urls {


@@ 212,7 212,7 @@ impl LinkProcessor {

                    trace!("Ready processing, linking new ref entry...");

                    let _ = entry.add_internal_link(&mut ref_entry)?;
                    let _ = entry.add_link(&mut ref_entry)?;
                },
                LinkQualification::Undecidable(e) => {
                    // error


@@ 271,8 271,8 @@ impl LinkQualification {
impl Default for LinkProcessor {
    fn default() -> Self {
        LinkProcessor {
            process_internal_links: true,
            create_internal_targets: false,
            process_links: true,
            create_targets: false,
            process_urls: true,
            process_refs: false
        }


@@ 286,7 286,7 @@ mod tests {
    use std::path::PathBuf;

    use libimagstore::store::Store;
    use libimagentrylink::linker::InternalLinker;
    use libimagentrylink::linkable::Linkable;

    fn setup_logging() {
        let _ = ::env_logger::try_init();


@@ 328,8 328,8 @@ mod tests {
        let _ = store.create(PathBuf::from("test-2.2")).unwrap();

        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(false)
            .process_links(true)
            .create_targets(false)
            .process_urls(false)
            .process_refs(false);



@@ 337,7 337,7 @@ mod tests {
        assert!(result.is_ok(), "Should be Ok(()): {:?}", result);

        {
            let base_links = base.get_internal_links();
            let base_links = base.links();
            assert!(base_links.is_ok());
            let base_links : Vec<_> = base_links.unwrap().collect();



@@ 347,7 347,7 @@ mod tests {

        {
            let link = store.get(PathBuf::from("test-2.2")).unwrap().unwrap();
            let link_links = link.get_internal_links();
            let link_links = link.links();
            assert!(link_links.is_ok());
            let link_links : Vec<_> = link_links.unwrap().collect();



@@ 368,8 368,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(false)
            .process_links(true)
            .create_targets(false)
            .process_urls(false)
            .process_refs(false);



@@ 389,8 389,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(true)
            .process_links(true)
            .create_targets(true)
            .process_urls(false)
            .process_refs(false);



@@ 398,7 398,7 @@ mod tests {
        assert!(result.is_ok(), "Should be Ok(()): {:?}", result);

        {
            let base_links = base.get_internal_links();
            let base_links = base.links();
            assert!(base_links.is_ok());
            let base_links : Vec<_> = base_links.unwrap().collect();



@@ 408,7 408,7 @@ mod tests {

        {
            let link = store.get(PathBuf::from("test-2.2")).unwrap().unwrap();
            let link_links = link.get_internal_links();
            let link_links = link.links();
            assert!(link_links.is_ok());
            let link_links : Vec<_> = link_links.unwrap().collect();



@@ 429,8 429,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(true)
            .process_links(true)
            .create_targets(true)
            .process_urls(true)
            .process_refs(false);



@@ 440,7 440,7 @@ mod tests {
        // The hash of "http://example.com" processed in the `libimagentrylink` way.
        let expected_link = "url/external/9c17e047f58f9220a7008d4f18152fee4d111d14";
        {
            let base_links = base.get_internal_links();
            let base_links = base.links();
            assert!(base_links.is_ok());
            let base_links : Vec<_> = base_links.unwrap().collect();



@@ 456,7 456,7 @@ mod tests {

        {
            let link = store.get(PathBuf::from(expected_link)).unwrap().unwrap();
            let link_links = link.get_internal_links();
            let link_links = link.links();
            assert!(link_links.is_ok());
            let link_links : Vec<_> = link_links.unwrap().collect();



@@ 479,8 479,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(false)
            .create_internal_targets(false)
            .process_links(false)
            .create_targets(false)
            .process_urls(false)
            .process_refs(true);



@@ 512,8 512,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(false)
            .create_internal_targets(false)
            .process_links(false)
            .create_targets(false)
            .process_urls(false)
            .process_refs(true);



@@ 545,8 545,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(false)
            .create_internal_targets(false)
            .process_links(false)
            .create_targets(false)
            .process_urls(false)
            .process_refs(false);



@@ 573,8 573,8 @@ mod tests {
        assert!(update.is_ok());

        let processor = LinkProcessor::default()
            .process_internal_links(true)
            .create_internal_targets(true)
            .process_links(true)
            .create_targets(true)
            .process_urls(false)
            .process_refs(false);



@@ 589,7 589,7 @@ mod tests {
    }

    #[test]
    fn test_process_one_existing_file_linked_with_internal_processing_switched_off() {
    fn test_process_one_existing_file_linked_with_processing_switched_off() {
        setup_logging();
        let store = get_store();



@@ 603,8 603,8 @@ mod tests {
        let _ = store.create(PathBuf::from("test-2.2")).unwrap();

        let processor = LinkProcessor::default()
            .process_internal_links(false)
            .create_internal_targets(false)
            .process_links(false)
            .create_targets(false)
            .process_urls(false)
            .process_refs(false);


M lib/entry/libimagentryurl/src/iter.rs => lib/entry/libimagentryurl/src/iter.rs +5 -5
@@ 79,7 79,7 @@ impl Iterator for ExternalFilterIter {
/// # See also
///
/// Also see `OnlyExternalIter` and `NoExternalIter` and the helper traits/functions
/// `OnlyInteralLinks`/`only_internal_links()` and `OnlyExternalLinks`/`only_urls()`.
/// `OnlyInteralLinks`/`only_links()` and `OnlyExternalLinks`/`only_urls()`.
pub trait SelectExternal {
    fn select_urls(self, b: bool) -> ExternalFilterIter;
}


@@ 130,7 130,7 @@ impl Iterator for NoExternalIter {
pub trait OnlyExternalLinks : Sized {
    fn only_urls(self) -> OnlyExternalIter ;

    fn no_internal_links(self) -> OnlyExternalIter {
    fn no_links(self) -> OnlyExternalIter {
        self.only_urls()
    }
}


@@ 142,15 142,15 @@ impl OnlyExternalLinks for LinkIter {
}

pub trait OnlyInternalLinks : Sized {
    fn only_internal_links(self) -> NoExternalIter;
    fn only_links(self) -> NoExternalIter;

    fn no_urls(self) -> NoExternalIter {
        self.only_internal_links()
        self.only_links()
    }
}

impl OnlyInternalLinks for LinkIter {
    fn only_internal_links(self) -> NoExternalIter {
    fn only_links(self) -> NoExternalIter {
        NoExternalIter::new(self)
    }
}

M lib/entry/libimagentryurl/src/linker.rs => lib/entry/libimagentryurl/src/linker.rs +4 -4
@@ 23,7 23,7 @@ use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::Entry;
use libimagutil::debug_result::DebugResult;
use libimagentrylink::linker::InternalLinker;
use libimagentrylink::linkable::Linkable;

use failure::Fallible as Result;
use toml::Value;


@@ 36,7 36,7 @@ use hex;

use crate::iter::UrlIter;

pub trait UrlLinker : InternalLinker {
pub trait UrlLinker : Linkable {

    /// Get the external links from the implementor object
    fn get_urls<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;


@@ 64,7 64,7 @@ impl UrlLinker for Entry {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
        self.links()
            .map(|iter| {
                debug!("Getting external links");
                iter.only_urls().urls(store)


@@ 130,7 130,7 @@ impl UrlLinker for Entry {
            }

            // then add an internal link to the new file or return an error if this fails
            let _ = self.add_internal_link(file.deref_mut())?;
            let _ = self.add_link(file.deref_mut())?;
            debug!("Added internal link");

            Ok((link_already_exists, file_id))