~matthiasbeyer/imag

ef17930c29e00ff9d8bc2a6138086ca9403af755 — Matthias Beyer 2 years ago f21b6e5
Rename interface

With this patch, the libimagentrylink library interface gets renamed.

The trait gets renamed to the more descriptive name "Linkable", the
functions get renamed to not contain any notion of "internal" anymore.

This patch also adapts the whole source tree for the new libimagentrylink
interface, also renaming variables to not contain "_internal_" anymore.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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::linker::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/linker.rs => lib/entry/libimagentrylink/src/linker.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 +1 -1
@@ 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::linker::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::linker::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::linker::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))