~matthiasbeyer/imag

47044d9ffea98e1f28efea113175cff61cfd9ef2 — Matthias Beyer 1 year, 7 months ago b3eb37d + e2216db
Pull changes from https://github.com/flip1995/imag clippy_fix

This pulls in the clippy fixes from Phil. From the request-pull:

-----8<-----
    I finally got to fixing all of the Clippy warnings in the imag codebase.
    `cargo test` passes, `cargo clippy` doesn't produce any warnings
    or errors.

    Some important notes:
      - I didn't pay attention to the line length of the changes, so it may
        have happened that some lines are now longer than 100 chars
      - Except two commits the commit messages are formatted as follows:
        * The first tag shows if the changes in the commit were
          automatically applied by `cargo fix --clippy -Zunstable-options`.
          Commits that were automatically applied may require closer review,
          since I didn't check those by hand and the Clippy fix feature is
          still unstable.
        * The other tags specify the subcrate that is affected by the
          commit. I created one commit for each subcrate, even when only one
          file (most of the time the `main.rs` file) was changed.
      - I created one commit, where I replace usages of `r#try!` with the
        `?` operator, since `try!` is now officially deprecated.
      - I created one commit, where I just allow Clippy lints. Either because
        the fix would require much more work or knowledge of the codebase or
        because it was a FP.

    This was pretty much work, but it helped detecting a few bugs in Clippy,
    where I was already able to open 3 or 4 PRs. So win-win I guess.

    [...] we got a net LoC decrease.
----->8-----
126 files changed, 891 insertions(+), 957 deletions(-)

M bin/core/imag-annotate/src/main.rs
M bin/core/imag-annotate/src/ui.rs
M bin/core/imag-category/src/main.rs
M bin/core/imag-category/src/ui.rs
M bin/core/imag-diagnostics/src/main.rs
M bin/core/imag-edit/src/main.rs
M bin/core/imag-edit/src/ui.rs
M bin/core/imag-git/src/main.rs
M bin/core/imag-gps/src/main.rs
M bin/core/imag-gps/src/ui.rs
M bin/core/imag-grep/src/main.rs
M bin/core/imag-header/src/main.rs
M bin/core/imag-header/src/ui.rs
M bin/core/imag-init/src/main.rs
M bin/core/imag-link/src/main.rs
M bin/core/imag-link/src/ui.rs
M bin/core/imag-markdown/src/ui.rs
M bin/core/imag-mv/src/main.rs
M bin/core/imag-ref/src/main.rs
M bin/core/imag-ref/src/ui.rs
M bin/core/imag-store/src/create.rs
M bin/core/imag-store/src/delete.rs
M bin/core/imag-store/src/get.rs
M bin/core/imag-store/src/retrieve.rs
M bin/core/imag-store/src/update.rs
M bin/core/imag-store/src/util.rs
M bin/core/imag-store/src/verify.rs
M bin/core/imag-tag/src/main.rs
M bin/core/imag-tag/src/ui.rs
M bin/core/imag-view/src/main.rs
M bin/core/imag-view/src/ui.rs
M bin/core/imag/src/main.rs
M bin/domain/imag-bookmark/src/main.rs
M bin/domain/imag-contact/src/create.rs
M bin/domain/imag-contact/src/edit.rs
M bin/domain/imag-contact/src/main.rs
M bin/domain/imag-contact/src/util.rs
M bin/domain/imag-diary/src/create.rs
M bin/domain/imag-diary/src/delete.rs
M bin/domain/imag-diary/src/list.rs
M bin/domain/imag-diary/src/main.rs
M bin/domain/imag-diary/src/view.rs
M bin/domain/imag-habit/src/main.rs
M bin/domain/imag-log/src/main.rs
M bin/domain/imag-mail/src/main.rs
M bin/domain/imag-mail/src/ui.rs
M bin/domain/imag-notes/src/main.rs
M bin/domain/imag-timetrack/src/cont.rs
M bin/domain/imag-timetrack/src/day.rs
M bin/domain/imag-timetrack/src/list.rs
M bin/domain/imag-timetrack/src/month.rs
M bin/domain/imag-timetrack/src/shell.rs
M bin/domain/imag-timetrack/src/start.rs
M bin/domain/imag-timetrack/src/stop.rs
M bin/domain/imag-timetrack/src/track.rs
M bin/domain/imag-timetrack/src/week.rs
M bin/domain/imag-timetrack/src/year.rs
M bin/domain/imag-todo/src/main.rs
M bin/domain/imag-wiki/src/main.rs
M lib/core/libimagerror/src/trace.rs
M lib/core/libimagrt/src/configuration.rs
M lib/core/libimagrt/src/logger.rs
M lib/core/libimagrt/src/runtime.rs
M lib/core/libimagstore/src/file_abstraction/fs.rs
M lib/core/libimagstore/src/file_abstraction/inmemory.rs
M lib/core/libimagstore/src/file_abstraction/mod.rs
M lib/core/libimagstore/src/store.rs
M lib/core/libimagstore/src/storeid.rs
M lib/core/libimagstore/src/util.rs
M lib/domain/libimagbookmark/src/collection.rs
M lib/domain/libimagcontact/src/store.rs
M lib/domain/libimagdiary/src/diary.rs
M lib/domain/libimagdiary/src/diaryid.rs
M lib/domain/libimagdiary/src/iter.rs
M lib/domain/libimagdiary/src/viewer.rs
M lib/domain/libimaghabit/src/habit.rs
M lib/domain/libimaghabit/src/instance.rs
M lib/domain/libimagmail/src/config.rs
M lib/domain/libimagmail/src/store.rs
M lib/domain/libimagtimetrack/src/constants.rs
M lib/domain/libimagtimetrack/src/iter/create.rs
M lib/domain/libimagtimetrack/src/iter/filter.rs
M lib/domain/libimagtimetrack/src/iter/storeid.rs
M lib/domain/libimagtimetrack/src/iter/tag.rs
M lib/domain/libimagtodo/src/taskstore.rs
M lib/domain/libimagwiki/src/store.rs
M lib/domain/libimagwiki/src/wiki.rs
M lib/entry/libimagentryannotation/src/annotateable.rs
M lib/entry/libimagentrycategory/src/category.rs
M lib/entry/libimagentrycategory/src/entry.rs
M lib/entry/libimagentrycategory/src/iter.rs
M lib/entry/libimagentrycategory/src/store.rs
M lib/entry/libimagentrydatetime/src/datepath/compiler.rs
M lib/entry/libimagentrydatetime/src/datetime.rs
M lib/entry/libimagentrydatetime/src/range.rs
M lib/entry/libimagentryedit/src/edit.rs
M lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs
M lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs
M lib/entry/libimagentryfilter/src/builtin/header/version/eq.rs
M lib/entry/libimagentryfilter/src/builtin/header/version/gt.rs
M lib/entry/libimagentryfilter/src/builtin/header/version/lt.rs
M lib/entry/libimagentryfilter/src/tags/mod.rs
M lib/entry/libimagentrygps/src/types.rs
M lib/entry/libimagentrylink/src/iter.rs
M lib/entry/libimagentrylink/src/link.rs
M lib/entry/libimagentrylink/src/linkable.rs
M lib/entry/libimagentrylink/src/storecheck.rs
M lib/entry/libimagentrymarkdown/src/html.rs
M lib/entry/libimagentrymarkdown/src/link.rs
M lib/entry/libimagentrymarkdown/src/processor.rs
M lib/entry/libimagentryref/src/reference.rs
M lib/entry/libimagentrytag/src/tag.rs
M lib/entry/libimagentrytag/src/tagable.rs
M lib/entry/libimagentryurl/src/iter.rs
M lib/entry/libimagentryurl/src/link.rs
M lib/entry/libimagentryurl/src/linker.rs
M lib/entry/libimagentryutil/src/iter.rs
M lib/entry/libimagentryview/src/builtin/md.rs
M lib/entry/libimagentryview/src/builtin/plain.rs
M lib/entry/libimagentryview/src/builtin/stdout.rs
M lib/entry/libimagentryview/src/viewer.rs
M lib/etc/libimaginteraction/src/ask.rs
M lib/etc/libimaginteraction/src/format.rs
M lib/etc/libimaginteraction/src/ui.rs
M lib/etc/libimagutil/src/date.rs
M lib/etc/libimagutil/src/key_value_split.rs
M bin/core/imag-annotate/src/main.rs => bin/core/imag-annotate/src/main.rs +22 -25
@@ 77,22 77,20 @@ fn main() {
                                    "Add annotations to entries",
                                    ui::build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "add"    => add(&rt),
                "remove" => remove(&rt),
                "list"   => list(&rt),
                other    => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            }
        });
    if let Some(name) = rt.cli().subcommand_name() {
        match name {
            "add"    => add(&rt),
            "remove" => remove(&rt),
            "list"   => list(&rt),
            other    => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        }
    }
}

fn add(rt: &Runtime) {


@@ 116,7 114,7 @@ fn add(rt: &Runtime) {
            .annotate(rt.store())
            .map_err_trace_exit_unwrap();

        let _ = annotation.edit_content(&rt).map_err_trace_exit_unwrap();
        annotation.edit_content(&rt).map_err_trace_exit_unwrap();

        for id in ids {
            let mut entry = rt.store().get(id.clone())


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

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

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


@@ 134,7 132,7 @@ fn add(rt: &Runtime) {
                .map_err(Error::from)
                .map_err_trace_exit_unwrap()
            {
                let _ = writeln!(rt.stdout(), "Name of the annotation: {}", annotation_id)
                writeln!(rt.stdout(), "Name of the annotation: {}", annotation_id)
                    .to_exit_code()
                    .unwrap_or_exit();
            } else {


@@ 160,7 158,7 @@ fn remove(rt: &Runtime) {
        })
        .into_iter();

    ids.into_iter().for_each(|id| {
    ids.for_each(|id| {
        let mut entry = rt.store()
            .get(id.clone())
            .map_err_trace_exit_unwrap()


@@ 178,7 176,7 @@ fn remove(rt: &Runtime) {
                let loc = an.get_location().clone();
                drop(an);

                let _ = rt
                rt
                    .store()
                    .delete(loc)
                    .map_err_trace_exit_unwrap();


@@ 205,10 203,9 @@ fn list(rt: &Runtime) {
        .into_iter();

    if ids.len() != 0 {
        let _ = ids
            .into_iter()
        ids
            .for_each(|id| {
                let _ = rt
                rt
                    .store()
                    .get(id.clone())
                    .map_err_trace_exit_unwrap()


@@ 239,7 236,7 @@ fn list(rt: &Runtime) {
}

fn list_annotation<'a>(rt: &Runtime, i: usize, a: FileLockEntry<'a>, with_text: bool) {
    let _ = if with_text {
    if with_text {
        writeln!(rt.stdout(),
                 "--- {i: >5} | {id}\n{text}\n\n",
                 i = i,

M bin/core/imag-annotate/src/ui.rs => bin/core/imag-annotate/src/ui.rs +0 -1
@@ 102,7 102,6 @@ impl IdPathProvider for PathProvider {
        fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
            subm.values_of("entry")
                .map(|v| v
                     .into_iter()
                     .map(PathBuf::from)
                     .map(|pb| pb.into_storeid())
                     .collect::<Result<Vec<_>>>()

M bin/core/imag-category/src/main.rs => bin/core/imag-category/src/main.rs +22 -24
@@ 70,25 70,23 @@ fn main() {
                                    "Add a category to entries and manage categories",
                                    ui::build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "set"               => set(&rt),
                "get"               => get(&rt),
                "list-category"     => list_category(&rt),
                "create-category"   => create_category(&rt),
                "delete-category"   => delete_category(&rt),
                "list-categories"   => list_categories(&rt),
                other               => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            }
        });
    if let Some(name) = rt.cli().subcommand_name() {
        match name {
            "set"               => set(&rt),
            "get"               => get(&rt),
            "list-category"     => list_category(&rt),
            "create-category"   => create_category(&rt),
            "delete-category"   => delete_category(&rt),
            "list-categories"   => list_categories(&rt),
            other               => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        }
    }
}

fn set(rt: &Runtime) {


@@ 103,7 101,7 @@ fn set(rt: &Runtime) {
        })
        .into_iter();

    StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
    StoreIdIterator::new(Box::new(sids.map(Ok)))
        .into_get_iter(rt.store())
        .trace_unwrap_exit()
        .map(|o| o.unwrap_or_else(|| {


@@ 111,7 109,7 @@ fn set(rt: &Runtime) {
            ::std::process::exit(1)
        }))
        .for_each(|mut entry| {
            let _ = entry
            entry
                .set_category_checked(rt.store(), &name)
                .map_err_trace_exit_unwrap();
        })


@@ 129,7 127,7 @@ fn get(rt: &Runtime) {
        })
        .into_iter();

    StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
    StoreIdIterator::new(Box::new(sids.map(Ok)))
        .into_get_iter(rt.store())
        .trace_unwrap_exit()
        .map(|o| o.unwrap_or_else(|| {


@@ 138,7 136,7 @@ fn get(rt: &Runtime) {
        }))
        .map(|entry| entry.get_category().map_err_trace_exit_unwrap())
        .for_each(|name| {
            let _ = writeln!(outlock, "{}", name).to_exit_code().unwrap_or_exit();
            writeln!(outlock, "{}", name).to_exit_code().unwrap_or_exit();
        })
}



@@ 190,7 188,7 @@ fn delete_category(rt: &Runtime) {

    if answer {
        info!("Deleting category '{}'", name);
        let _ = rt
        rt
            .store()
            .delete_category(&name)
            .map_err_trace_exit_unwrap();

M bin/core/imag-category/src/ui.rs => bin/core/imag-category/src/ui.rs +0 -1
@@ 111,7 111,6 @@ impl IdPathProvider for PathProvider {
        fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
            subm.values_of(field)
                .map(|v| v
                     .into_iter()
                     .map(PathBuf::from)
                     .map(|pb| pb.into_storeid())
                     .collect::<Result<Vec<_>>>()

M bin/core/imag-diagnostics/src/main.rs => bin/core/imag-diagnostics/src/main.rs +4 -4
@@ 92,9 92,9 @@ impl Diagnostic {
                    Some(_) => "Non-String type in 'imag.version'".to_owned(),
                    None => "No version".to_owned(),
                })
                .unwrap_or("Error reading version".to_owned()),
                .unwrap_or_else(|_| "Error reading version".to_owned()),
            header_sections: match entry.get_header() {
                &Value::Table(ref map) => map.keys().count(),
                Value::Table(ref map) => map.keys().count(),
                _ => 0
            },
            bytecount_content: entry.get_content().as_str().len(),


@@ 147,7 147,7 @@ fn main() {
        .into_get_iter()
        .map(|e| {
            e.map_err_trace_exit_unwrap()
                .ok_or_else(|| Error::from(err_msg("Unable to get entry".to_owned())))
                .ok_or_else(|| err_msg("Unable to get entry".to_owned()))
                .map_err_trace_exit_unwrap()
        })
        .map(|e| {


@@ 258,7 258,7 @@ fn get_config(rt: &Runtime, s: &'static str) -> Option<String> {
            .map_err(Error::from)
            .map_err_trace_exit_unwrap()
            .map(|opt| match opt {
                &Value::String(ref s) => s.to_owned(),
                Value::String(ref s) => s.to_owned(),
                _ => {
                    error!("Config type wrong: 'rt.progressbar_style' should be a string");
                    ::std::process::exit(1)

M bin/core/imag-edit/src/main.rs => bin/core/imag-edit/src/main.rs +4 -4
@@ 73,7 73,7 @@ fn main() {
        })
        .into_iter();

    StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
    StoreIdIterator::new(Box::new(sids.map(Ok)))
        .into_get_iter(rt.store())
        .trace_unwrap_exit()
        .map(|o| o.unwrap_or_else(|| {


@@ 82,15 82,15 @@ fn main() {
        }))
        .for_each(|mut entry| {
            if edit_header {
                let _ = entry
                entry
                    .edit_header_and_content(&rt)
                    .map_err_trace_exit_unwrap();
            } else if edit_header_only {
                let _ = entry
                entry
                    .edit_header(&rt)
                    .map_err_trace_exit_unwrap();
            } else {
                let _ = entry
                entry
                    .edit_content(&rt)
                    .map_err_trace_exit_unwrap();
            }

M bin/core/imag-edit/src/ui.rs => bin/core/imag-edit/src/ui.rs +0 -1
@@ 57,7 57,6 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("entry")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()

M bin/core/imag-git/src/main.rs => bin/core/imag-git/src/main.rs +12 -16
@@ 116,20 116,16 @@ fn main() {
    debug!("Adding args = {:?}", args);
    command.args(&args);

    match rt.cli().subcommand() {
        (external, Some(ext_m)) => {
            command.arg(external);
            let args = ext_m
                .values_of("")
                .map(|vs| vs.map(String::from).collect())
                .unwrap_or_else(|| vec![]);

            debug!("Adding subcommand '{}' and args = {:?}", external, args);
            command.args(&args);
        },
        _ => {},
    if let (external, Some(ext_m)) = rt.cli().subcommand() {
        command.arg(external);
        let args = ext_m
            .values_of("")
            .map(|vs| vs.map(String::from).collect())
            .unwrap_or_else(|| vec![]);

        debug!("Adding subcommand '{}' and args = {:?}", external, args);
        command.args(&args);
    }

    let mut out = rt.stdout();

    debug!("Calling: {:?}", command);


@@ 151,19 147,19 @@ fn main() {
            debug!("Error calling git");
            match e.kind() {
                ErrorKind::NotFound => {
                    let _ = writeln!(out, "Cannot find 'git' executable")
                    writeln!(out, "Cannot find 'git' executable")
                        .to_exit_code()
                        .unwrap_or_exit();
                    ::std::process::exit(1);
                },
                ErrorKind::PermissionDenied => {
                    let _ = writeln!(out, "No permission to execute: 'git'")
                    writeln!(out, "No permission to execute: 'git'")
                        .to_exit_code()
                        .unwrap_or_exit();
                    ::std::process::exit(1);
                },
                _ => {
                    let _ = writeln!(out, "Error spawning: {:?}", e)
                    writeln!(out, "Error spawning: {:?}", e)
                        .to_exit_code()
                        .unwrap_or_exit();
                    ::std::process::exit(1);

M bin/core/imag-gps/src/main.rs => bin/core/imag-gps/src/main.rs +21 -22
@@ 48,7 48,7 @@ use std::io::Write;
use std::process::exit;
use std::str::FromStr;

use failure::Error;

use failure::err_msg;

use libimagstore::storeid::StoreId;


@@ 69,21 69,20 @@ fn main() {
                                    "Add GPS coordinates to entries",
                                    ui::build_ui);

    rt.cli().subcommand_name()
        .map(|name| {
            match name {
                "add"    => add(&rt),
                "remove" => remove(&rt),
                "get"    => get(&rt),
                other    => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                }
    if let Some(name) = rt.cli().subcommand_name() {
        match name {
            "add"    => add(&rt),
            "remove" => remove(&rt),
            "get"    => get(&rt),
            other    => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            }
        });
        }
    }
}

fn rt_get_ids(rt: &Runtime) -> Vec<StoreId> {


@@ 100,11 99,11 @@ fn add(rt: &Runtime) {
    let c = {
        let parse = |value: &str| -> (i64, i64, i64) {
            debug!("Parsing '{}' into degree, minute and second", value);
            let ary = value.split(".")
            let ary = value.split('.')
                .map(|v| {debug!("Parsing = {}", v); v})
                .map(FromStr::from_str)
                .map(|elem| {
                    elem.or_else(|_| Err(Error::from(err_msg("Error while converting number"))))
                    elem.or_else(|_| Err(err_msg("Error while converting number")))
                        .map_err_trace_exit_unwrap()
                })
                .collect::<Vec<i64>>();


@@ 146,7 145,7 @@ fn add(rt: &Runtime) {
                .set_coordinates(c.clone())
                .map_err_trace_exit_unwrap();

            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();
        });
}



@@ 177,10 176,10 @@ fn remove(rt: &Runtime) {
                .map_err_trace_exit_unwrap(); // The parsing of the deleted values failed

            if print_removed {
                let _ = writeln!(rt.stdout(), "{}", removed_value).to_exit_code().unwrap_or_exit();
                writeln!(rt.stdout(), "{}", removed_value).to_exit_code().unwrap_or_exit();
            }

            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();
        });
}



@@ 205,9 204,9 @@ fn get(rt: &Runtime) {
                    exit(1)
                });

            let _ = writeln!(stdout, "{}", value).to_exit_code().unwrap_or_exit();
            writeln!(stdout, "{}", value).to_exit_code().unwrap_or_exit();

            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();
        })

}

M bin/core/imag-gps/src/ui.rs => bin/core/imag-gps/src/ui.rs +0 -1
@@ 103,7 103,6 @@ impl IdPathProvider for PathProvider {
        fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
            subm.values_of(field)
                .map(|v| v
                     .into_iter()
                     .map(PathBuf::from)
                     .map(|pb| pb.into_storeid())
                     .collect::<Result<Vec<_>>>()

M bin/core/imag-grep/src/main.rs => bin/core/imag-grep/src/main.rs +13 -9
@@ 90,14 90,18 @@ fn main() {
        .map_err_trace_exit_unwrap()
        .into_get_iter()
        .filter_map(|res| res.map_err_trace_exit_unwrap())
        .filter(|entry| pattern.is_match(entry.get_content()))
        .map(|entry| show(&rt, &entry, &pattern, &opts, &mut count))
        .filter_map(|entry| if pattern.is_match(entry.get_content()) {
            show(&rt, &entry, &pattern, &opts, &mut count);
            Some(())
        } else {
            None
        })
        .count();

    if opts.count {
        let _ = writeln!(rt.stdout(), "{}", count).to_exit_code().unwrap_or_exit();
        writeln!(rt.stdout(), "{}", count).to_exit_code().unwrap_or_exit();
    } else if !opts.files_with_matches {
        let _ = writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches",
        writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches",
                 overall_count,
                 count,
                 overall_count - count)


@@ 108,23 112,23 @@ fn main() {

fn show(rt: &Runtime, e: &Entry, re: &Regex, opts: &Options, count: &mut usize) {
    if opts.files_with_matches {
        let _ = writeln!(rt.stdout(), "{}", e.get_location()).to_exit_code().unwrap_or_exit();
        writeln!(rt.stdout(), "{}", e.get_location()).to_exit_code().unwrap_or_exit();
    } else if opts.count {
        *count += 1;
    } else {
        let _ = writeln!(rt.stdout(), "{}:", e.get_location()).to_exit_code().unwrap_or_exit();
        writeln!(rt.stdout(), "{}:", e.get_location()).to_exit_code().unwrap_or_exit();
        for capture in re.captures_iter(e.get_content()) {
            for mtch in capture.iter() {
                if let Some(m) = mtch {
                    let _ = writeln!(rt.stdout(), " '{}'", m.as_str()).to_exit_code().unwrap_or_exit();
                    writeln!(rt.stdout(), " '{}'", m.as_str()).to_exit_code().unwrap_or_exit();
                }
            }
        }

        let _ = writeln!(rt.stdout(), "").to_exit_code().unwrap_or_exit();
        writeln!(rt.stdout()).to_exit_code().unwrap_or_exit();
        *count += 1;
    }

    let _ = rt.report_touched(e.get_location()).unwrap_or_exit();
    rt.report_touched(e.get_location()).unwrap_or_exit();
}


M bin/core/imag-header/src/main.rs => bin/core/imag-header/src/main.rs +1 -1
@@ 93,7 93,7 @@ fn main() {
        })
        .into_iter();

    let iter = StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
    let iter = StoreIdIterator::new(Box::new(sids.map(Ok)))
        .into_get_iter(rt.store())
        .trace_unwrap_exit()
        .filter_map(|x| x);

M bin/core/imag-header/src/ui.rs => bin/core/imag-header/src/ui.rs +0 -1
@@ 237,7 237,6 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("id")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()

M bin/core/imag-init/src/main.rs => bin/core/imag-init/src/main.rs +22 -22
@@ 54,9 54,9 @@ use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagrt::runtime::Runtime;

const CONFIGURATION_STR : &'static str = include_str!("../imagrc.toml");
const CONFIGURATION_STR : &str = include_str!("../imagrc.toml");

const GITIGNORE_STR : &'static str = r#"
const GITIGNORE_STR : &str = r#"
# We ignore the imagrc.toml file by default
#
# That is because we expect the user to put


@@ 87,10 87,10 @@ fn main() {
                .map(PathBuf::from)
                .map(|mut p| { p.push(".imag"); p })
                .map(|path| if path.exists() {
                    let _ = writeln!(out, "Path '{:?}' already exists!", path)
                    writeln!(out, "Path '{:?}' already exists!", path)
                        .to_exit_code()
                        .unwrap_or_exit();
                    let _ = writeln!(out, "Cannot continue.")
                    writeln!(out, "Cannot continue.")
                        .to_exit_code()
                        .unwrap_or_exit();
                    ::std::process::exit(1)


@@ 105,7 105,7 @@ fn main() {
        store_path.push("store");
        println!("Creating {}", store_path.display());

        let _ = ::std::fs::create_dir_all(store_path)
        ::std::fs::create_dir_all(store_path)
            .expect("Failed to create directory");
    }



@@ 115,7 115,7 @@ fn main() {
        config_path
    };

    let _ = OpenOptions::new()
    OpenOptions::new()
        .write(true)
        .create(true)
        .open(config_path)


@@ 126,14 126,14 @@ fn main() {
                get_config()
            };

            let _ = f.write_all(content.as_bytes())
            f.write_all(content.as_bytes())
                .expect("Failed to write complete config to file");
        })
        .expect("Failed to open new configuration file");

    if find_command("git").is_some() && !matches.is_present("nogit") {
        // we initialize a git repository
        let _ = writeln!(out, "Going to initialize a git repository in the imag directory...")
        writeln!(out, "Going to initialize a git repository in the imag directory...")
            .to_exit_code()
            .unwrap_or_exit();



@@ 143,12 143,12 @@ fn main() {
            gitignore_path.to_str().map(String::from).expect("Cannot convert path to string")
        };

        let _ = OpenOptions::new()
        OpenOptions::new()
            .write(true)
            .create(true)
            .open(gitignore_path.clone())
            .map(|mut f| {
                let _ = f.write_all(GITIGNORE_STR.as_bytes())
                f.write_all(GITIGNORE_STR.as_bytes())
                    .expect("Failed to write complete gitignore to file");
            })
            .expect("Failed to open new configuration file");


@@ 164,14 164,14 @@ fn main() {
                .expect("Calling 'git init' failed");

            if output.status.success() {
                let _ = writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                let _ = writeln!(out, "'git {} {} --no-pager init' succeeded", worktree, gitdir)
                writeln!(out, "'git {} {} --no-pager init' succeeded", worktree, gitdir)
                    .to_exit_code()
                    .unwrap_or_exit();
            } else {
                let _ = writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                ::std::process::exit(output.status.code().unwrap_or(1));


@@ 184,14 184,14 @@ fn main() {
                .output()
                .expect("Calling 'git add' failed");
            if output.status.success() {
                let _ = writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                let _ = writeln!(out, "'git {} {} --no-pager add {}' succeeded", worktree, gitdir, gitignore_path)
                writeln!(out, "'git {} {} --no-pager add {}' succeeded", worktree, gitdir, gitignore_path)
                    .to_exit_code()
                    .unwrap_or_exit();
            } else {
                let _ = writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                ::std::process::exit(output.status.code().unwrap_or(1));


@@ 204,30 204,30 @@ fn main() {
                .output()
                .expect("Calling 'git commit' failed");
            if output.status.success() {
                let _ = writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stdout).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                let _ = writeln!(out, "'git {} {} --no-pager commit {} -m 'Initial import'' succeeded", worktree, gitdir, gitignore_path)
                writeln!(out, "'git {} {} --no-pager commit {} -m 'Initial import'' succeeded", worktree, gitdir, gitignore_path)
                    .to_exit_code()
                    .unwrap_or_exit();
            } else {
                let _ = writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                writeln!(out, "{}", String::from_utf8(output.stderr).expect("No UTF-8 output"))
                    .to_exit_code()
                    .unwrap_or_exit();
                ::std::process::exit(output.status.code().unwrap_or(1));
            }
        }

        let _ = writeln!(out, "git stuff finished!")
        writeln!(out, "git stuff finished!")
            .to_exit_code()
            .unwrap_or_exit();
    } else {
        let _ = writeln!(out, "No git repository will be initialized")
        writeln!(out, "No git repository will be initialized")
            .to_exit_code()
            .unwrap_or_exit();
    }

    let _ = writeln!(out, "Ready. Have fun with imag!")
    writeln!(out, "Ready. Have fun with imag!")
        .to_exit_code()
        .unwrap_or_exit();
}

M bin/core/imag-link/src/main.rs => bin/core/imag-link/src/main.rs +19 -18
@@ 59,7 59,7 @@ extern crate libimagutil;
use std::io::Write;
use std::path::PathBuf;

use failure::Error;

use failure::err_msg;

use libimagentryurl::linker::UrlLinker;


@@ 102,7 102,7 @@ fn main() {
        ::std::process::exit(exit_code);
    }

    let _ = rt.cli()
    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {


@@ 120,12 120,13 @@ fn main() {
        })
        .or_else(|| {
            if let (Some(from), Some(to)) = (rt.cli().value_of("from"), rt.cli().values_of("to")) {
                Some(link_from_to(&rt, from, to))
                link_from_to(&rt, from, to);
                Some(())
            } else {
                warn_exit("No commandline call", 1)
            }
        })
        .ok_or_else(|| Error::from(err_msg("No commandline call".to_owned())))
        .ok_or_else(|| err_msg("No commandline call".to_owned()))
        .map_err_trace_exit_unwrap();
}



@@ 150,7 151,7 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)

    for entry in to {
        debug!("Handling 'to' entry: {:?}", entry);
        if !rt.store().get(PathBuf::from(entry)).map_err_trace_exit_unwrap().is_some() {
        if rt.store().get(PathBuf::from(entry)).map_err_trace_exit_unwrap().is_none() {
            debug!("Linking externally: {:?} -> {:?}", from, entry);
            let url = Url::parse(entry).unwrap_or_else(|e| {
                error!("Error parsing URL: {:?}", e);


@@ 162,7 163,7 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)
                .map_err_trace_exit_unwrap()
                .into_iter();

            let _ = rt.report_all_touched(iter).unwrap_or_exit();
            rt.report_all_touched(iter).unwrap_or_exit();
        } else {
            debug!("Linking internally: {:?} -> {:?}", from, entry);



@@ 181,18 182,18 @@ fn link_from_to<'a, I>(rt: &'a Runtime, from: &'a str, to: I)
                    ::std::process::exit(1)
                },
            };
            let _ = from_entry
            from_entry
                .add_link(&mut to_entry)
                .map_err_trace_exit_unwrap();

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


        info!("Ok: {} -> {}", from, entry);
    }

    let _ = rt.report_touched(from_entry.get_location()).unwrap_or_exit();
    rt.report_touched(from_entry.get_location()).unwrap_or_exit();
}

fn remove_linking(rt: &Runtime) {


@@ 221,11 222,11 @@ fn remove_linking(rt: &Runtime) {
        .for_each(|id| match rt.store().get(id.clone()) {
            Err(e) => trace_error(&e),
            Ok(Some(mut to_entry)) => {
                let _ = to_entry
                to_entry
                    .remove_link(&mut from)
                    .map_err_trace_exit_unwrap();

                let _ = rt.report_touched(to_entry.get_location()).unwrap_or_exit();
                rt.report_touched(to_entry.get_location()).unwrap_or_exit();
            },
            Ok(None) => {
                // looks like this is not an entry, but a filesystem URI and therefor an


@@ 247,7 248,7 @@ fn remove_linking(rt: &Runtime) {
            }
        });

    let _ = rt.report_touched(from.get_location()).unwrap_or_exit();
    rt.report_touched(from.get_location()).unwrap_or_exit();
}

fn unlink(rt: &Runtime) {


@@ 270,7 271,7 @@ fn unlink(rt: &Runtime) {
                .unlink(rt.store())
                .map_err_trace_exit_unwrap();

            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();
        });
}



@@ 304,7 305,7 @@ fn list_linkings(rt: &Runtime) {

                        if let Some(link) = link {
                            if list_plain {
                                let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link)
                                writeln!(rt.stdout(), "{: <3}: {}", i, link)
                                    .to_exit_code()
                                    .unwrap_or_exit();
                            } else {


@@ 323,7 324,7 @@ fn list_linkings(rt: &Runtime) {
                                    .into_string();

                                if list_plain {
                                    let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link)
                                    writeln!(rt.stdout(), "{: <3}: {}", i, link)
                                        .to_exit_code()
                                        .unwrap_or_exit();
                                } else {


@@ 332,14 333,14 @@ fn list_linkings(rt: &Runtime) {
                            })
                    }

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

                },
                Ok(None)        => warn!("Not found: {}", id),
                Err(e)          => trace_error(&e),
            }

            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();
        });

    if !list_plain {


@@ 409,7 410,7 @@ mod tests {
        }
    }

    fn links_toml_value<'a, I: IntoIterator<Item = &'static str>>(links: I) -> Value {
    fn links_toml_value<I: IntoIterator<Item = &'static str>>(links: I) -> Value {
        Value::Array(links
                         .into_iter()
                         .map(|s| Value::String(s.to_owned()))

M bin/core/imag-link/src/ui.rs => bin/core/imag-link/src/ui.rs +0 -1
@@ 121,7 121,6 @@ impl IdPathProvider for PathProvider {
        fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
            subm.values_of(field)
                .map(|v| v
                     .into_iter()
                     .map(PathBuf::from)
                     .map(|pb| pb.into_storeid())
                     .collect::<Result<Vec<_>>>()

M bin/core/imag-markdown/src/ui.rs => bin/core/imag-markdown/src/ui.rs +0 -1
@@ 50,7 50,6 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("entry")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()

M bin/core/imag-mv/src/main.rs => bin/core/imag-mv/src/main.rs +4 -4
@@ 118,11 118,11 @@ fn main() {
            });

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

    let _ = rt
    rt
        .store()
        .move_by_id(sourcename.clone(), destname.clone())
        .map_err(|e| { // on error, re-add links


@@ 132,7 132,7 @@ fn main() {
        })
        .map_err_trace_exit_unwrap();

    let _ = rt.report_touched(&destname).unwrap_or_exit();
    rt.report_touched(&destname).unwrap_or_exit();

    // re-add links to moved entry
    relink(rt.store(), destname, &mut linked_entries);


@@ 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_link(&mut link).map_err_trace_exit_unwrap();
        entry.add_link(&mut link).map_err_trace_exit_unwrap();
    }
}

M bin/core/imag-ref/src/main.rs => bin/core/imag-ref/src/main.rs +19 -21
@@ 69,24 69,22 @@ fn main() {
                                    &version,
                                    "Reference files outside of the store",
                                    build_ui);
    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call: {}", name);
            match name {
                "deref"     => deref(&rt),
                "create"    => create(&rt),
                "remove"    => remove(&rt),
                "list-dead" => list_dead(&rt),
                other => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            };
        });
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call: {}", name);
        match name {
            "deref"     => deref(&rt),
            "create"    => create(&rt),
            "remove"    => remove(&rt),
            "list-dead" => list_dead(&rt),
            other => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        };
    }
}

fn deref(rt: &Runtime) {


@@ 121,7 119,7 @@ fn deref(rt: &Runtime) {
                    .and_then(|s| writeln!(outlock, "{}", s).map_err(Error::from))
                    .map_err_trace_exit_unwrap();

                    let _ = rt.report_touched(&id).unwrap_or_exit();
                    rt.report_touched(&id).unwrap_or_exit();
                },
                None => {
                    error!("No entry for id '{}' found", id);


@@ 159,7 157,7 @@ fn remove(rt: &Runtime) {
                        ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output)
                            .map_err_trace_exit_unwrap()
                    {
                        let _ = entry.as_ref_with_hasher_mut::<DefaultHasher>()
                        entry.as_ref_with_hasher_mut::<DefaultHasher>()
                            .remove_ref()
                            .map_err_trace_exit_unwrap();
                    } else {


@@ 208,7 206,7 @@ fn list_dead(rt: &Runtime) {
                            .map_err(Error::from)
                            .map_err_trace_exit_unwrap();

                            let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                            rt.report_touched(entry.get_location()).unwrap_or_exit();
                        }
                    }
                }

M bin/core/imag-ref/src/ui.rs => bin/core/imag-ref/src/ui.rs +0 -1
@@ 137,7 137,6 @@ impl IdPathProvider for PathProvider {
        fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
            subm.values_of("ID")
                .map(|v| v
                     .into_iter()
                     .map(PathBuf::from)
                     .map(|pb| pb.into_storeid())
                     .collect::<Result<Vec<_>>>()

M bin/core/imag-store/src/create.rs => bin/core/imag-store/src/create.rs +2 -2
@@ 63,7 63,7 @@ pub fn create(rt: &Runtime) {
    }
    .map_err_trace_exit_unwrap();

    let _ = rt.report_touched(&path).unwrap_or_exit();
    rt.report_touched(&path).unwrap_or_exit();
}

fn create_from_cli_spec(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> Result<()> {


@@ 84,7 84,7 @@ fn create_from_cli_spec(rt: &Runtime, matches: &ArgMatches, path: &StoreId) -> R
    debug!("Got content with len = {}", content.len());

    let header = matches.subcommand_matches("entry")
        .map_or_else(|| Entry::default_header(),
        .map_or_else(Entry::default_header,
            |entry_matches| build_toml_header(entry_matches, Entry::default_header()));

    create_with_content_and_header(rt, path, content, header)

M bin/core/imag-store/src/delete.rs => bin/core/imag-store/src/delete.rs +1 -1
@@ 31,7 31,7 @@ pub fn delete(rt: &Runtime) {
    let path  = StoreId::new(path).map_err_trace_exit_unwrap();
    debug!("Deleting file at {:?}", id);

    let _ = rt.store()
    rt.store()
        .delete(path)
        .map_warn_err(|e| format!("Error: {:?}", e))
        .map_err_trace_exit_unwrap();

M bin/core/imag-store/src/get.rs => bin/core/imag-store/src/get.rs +2 -2
@@ 34,10 34,10 @@ pub fn get(rt: &Runtime) {
    let path  = StoreId::new(path).map_err_trace_exit_unwrap();
    debug!("path = {:?}", path);

    let _ = match rt.store().get(path.clone()).map_err_trace_exit_unwrap() {
    match rt.store().get(path.clone()).map_err_trace_exit_unwrap() {
        Some(entry) => {
            print_entry(rt, scmd, entry);
            let _ = rt.report_touched(&path).unwrap_or_exit();
            rt.report_touched(&path).unwrap_or_exit();
        },
        None        => info!("No entry found"),
    };

M bin/core/imag-store/src/retrieve.rs => bin/core/imag-store/src/retrieve.rs +17 -19
@@ 31,30 31,28 @@ use libimagerror::exit::ExitUnwrap;
use libimagutil::debug_result::*;

pub fn retrieve(rt: &Runtime) {
    rt.cli()
        .subcommand_matches("retrieve")
        .map(|scmd| {
            // unwrap() is safe as arg is required
            let id    = scmd.value_of("id").unwrap();
            let path  = PathBuf::from(id);
            let path  = StoreId::new(path).map_err_trace_exit_unwrap();
            debug!("path = {:?}", path);
    if let Some(scmd) = rt.cli().subcommand_matches("retrieve") {
        // unwrap() is safe as arg is required
        let id    = scmd.value_of("id").unwrap();
        let path  = PathBuf::from(id);
        let path  = StoreId::new(path).map_err_trace_exit_unwrap();
        debug!("path = {:?}", path);

            rt.store()
                .retrieve(path.clone())
                .map(|e| print_entry(rt, scmd, e))
                .map_dbg_str("No entry")
                .map_dbg(|e| format!("{:?}", e))
                .map_err_trace_exit_unwrap();
        rt.store()
            .retrieve(path.clone())
            .map(|e| print_entry(rt, scmd, e))
            .map_dbg_str("No entry")
            .map_dbg(|e| format!("{:?}", e))
            .map_err_trace_exit_unwrap();

            let _ = rt.report_touched(&path).unwrap_or_exit();
        });
        rt.report_touched(&path).unwrap_or_exit();
    }
}

pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {
    if do_print_raw(scmd) {
        debug!("Printing raw content...");
        let _ = writeln!(rt.stdout(), "{}", e.to_str().map_err_trace_exit_unwrap())
        writeln!(rt.stdout(), "{}", e.to_str().map_err_trace_exit_unwrap())
            .to_exit_code()
            .unwrap_or_exit();
    } else if do_filter(scmd) {


@@ 73,7 71,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {
                unimplemented!()
            } else {
                debug!("Printing header as TOML...");
                let _ = writeln!(rt.stdout(), "{}", e.get_header())
                writeln!(rt.stdout(), "{}", e.get_header())
                    .to_exit_code()
                    .unwrap_or_exit();
            }


@@ 81,7 79,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {

        if do_print_content(scmd) {
            debug!("Printing content...");
            let _ = writeln!(rt.stdout(), "{}", e.get_content())
            writeln!(rt.stdout(), "{}", e.get_content())
                    .to_exit_code()
                    .unwrap_or_exit();
        }

M bin/core/imag-store/src/update.rs => bin/core/imag-store/src/update.rs +5 -6
@@ 39,17 39,16 @@ pub fn update(rt: &Runtime) {
            {
                let e = locked_e.deref_mut();

                scmd.value_of("content")
                    .map(|new_content| {
                        *e.get_content_mut() = String::from(new_content);
                        debug!("New content set");
                    });
                if let Some(new_content) = scmd.value_of("content") {
                    *e.get_content_mut() = String::from(new_content);
                    debug!("New content set");
                }

                *e.get_header_mut() = build_toml_header(scmd, e.get_header().clone());
                debug!("New header set");
            }

            let _ = rt.report_touched(locked_e.get_location()).unwrap_or_exit();
            rt.report_touched(locked_e.get_location()).unwrap_or_exit();
        });
}


M bin/core/imag-store/src/util.rs => bin/core/imag-store/src/util.rs +9 -11
@@ 29,7 29,7 @@ use libimagutil::key_value_split::IntoKeyValue;
pub fn build_toml_header(matches: &ArgMatches, mut header: Value) -> Value {
    debug!("Building header from cli spec");
    if let Some(headerspecs) = matches.values_of("header") {
        let kvs = headerspecs.into_iter()
        let kvs = headerspecs
                            .filter_map(|hs| {
                                debug!("- Processing: '{}'", hs);
                                let kv = String::from(hs).into_kv();


@@ 40,10 40,8 @@ pub fn build_toml_header(matches: &ArgMatches, mut header: Value) -> Value {
            let (key, value) = tpl.into();
            debug!("Splitting: {:?}", key);
            let mut split = key.split('.');
            match (split.next(), &mut header) {
                (Some(cur), &mut Value::Table(ref mut hdr)) =>
                    insert_key_into(String::from(cur), &mut split, Cow::Owned(value), hdr),
                _ => { }
            if let (Some(cur), &mut Value::Table(ref mut hdr)) = (split.next(), &mut header) {
                insert_key_into(String::from(cur), &mut split, Cow::Owned(value), hdr);
            }
        }
    }


@@ 58,27 56,27 @@ fn insert_key_into<'a>(current: String,
                   map: &mut Map<String, Value>) {
    let next = rest_path.next();

    if next.is_none() {
        debug!("Inserting into {:?} = {:?}", current, value);
        map.insert(current, parse_value(value));
    } else {
    if let Some(next) = next {
        debug!("Inserting into {:?} ... = {:?}", current, value);
        match map.entry(current) {
            Entry::Occupied(ref mut e) => {
                match *e.get_mut() {
                    Value::Table(ref mut t) => {
                        insert_key_into(String::from(next.unwrap()), rest_path, value, t);
                        insert_key_into(String::from(next), rest_path, value, t);
                    },
                    _ => unreachable!(),
                }
            },
            Entry::Vacant(v) => { v.insert(Value::Table( {
                let mut submap = Map::new();
                insert_key_into(String::from(next.unwrap()), rest_path, value, &mut submap);
                insert_key_into(String::from(next), rest_path, value, &mut submap);
                debug!("Inserting submap = {:?}", submap);
                submap }));
            }
        }
    } else {
        debug!("Inserting into {:?} = {:?}", current, value);
        map.insert(current, parse_value(value));
    }
}


M bin/core/imag-store/src/verify.rs => bin/core/imag-store/src/verify.rs +1 -1
@@ 48,7 48,7 @@ pub fn verify(rt: &Runtime) {
            };

            info!("{: >6} | {: >14} | {:?}", verify, content_len, p.deref());
            let _ = rt.report_touched(fle.get_location()).unwrap_or_exit();
            rt.report_touched(fle.get_location()).unwrap_or_exit();
            status
        });


M bin/core/imag-tag/src/main.rs => bin/core/imag-tag/src/main.rs +22 -23
@@ 93,9 93,8 @@ fn main() {
        })
        .into_iter();

    rt.cli()
        .subcommand_name()
        .map(|name| match name {
    if let Some(name) = rt.cli().subcommand_name() {
        match name {
            "list" => for id in ids {
                list(id, &rt)
            },


@@ 118,7 117,8 @@ fn main() {
                    .code()
                    .map(::std::process::exit);
            },
        });
        }
    }
}

fn alter(rt: &Runtime, path: StoreId, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {


@@ 126,21 126,21 @@ fn alter(rt: &Runtime, path: StoreId, add: Option<Vec<Tag>>, rem: Option<Vec<Tag
        Ok(Some(mut e)) => {
            debug!("Entry header now = {:?}", e.get_header());

            add.map(|tags| {
                    debug!("Adding tags = '{:?}'", tags);
                    for tag in tags {
                        debug!("Adding tag '{:?}'", tag);
                        if let Err(e) = e.add_tag(tag) {
                            trace_error(&e);
                        } else {
                            debug!("Adding tag worked");
                        }
            if let Some(tags) = add {
                debug!("Adding tags = '{:?}'", tags);
                for tag in tags {
                    debug!("Adding tag '{:?}'", tag);
                    if let Err(e) = e.add_tag(tag) {
                        trace_error(&e);
                    } else {
                        debug!("Adding tag worked");
                    }
                }); // it is okay to ignore a None here
                }
            } // it is okay to ignore a None here

            debug!("Entry header now = {:?}", e.get_header());

            rem.map(|tags| {
            if let Some(tags) = rem {
                debug!("Removing tags = '{:?}'", tags);
                for tag in tags {
                    debug!("Removing tag '{:?}'", tag);


@@ 148,7 148,7 @@ fn alter(rt: &Runtime, path: StoreId, add: Option<Vec<Tag>>, rem: Option<Vec<Tag
                        trace_error(&e);
                    }
                }
            }); // it is okay to ignore a None here
            } // it is okay to ignore a None here

            debug!("Entry header now = {:?}", e.get_header());



@@ 164,7 164,7 @@ fn alter(rt: &Runtime, path: StoreId, add: Option<Vec<Tag>>, rem: Option<Vec<Tag
        },
    }

    let _ = rt.report_touched(&path).unwrap_or_exit();
    rt.report_touched(&path).unwrap_or_exit();
}

fn list(path: StoreId, rt: &Runtime) {


@@ 193,7 193,7 @@ fn list(path: StoreId, rt: &Runtime) {

    if line_out {
        for tag in &tags {
            let _ = writeln!(rt.stdout(), "{}", tag)
            writeln!(rt.stdout(), "{}", tag)
                .to_exit_code()
                .unwrap_or_exit();
        }


@@ 201,18 201,18 @@ fn list(path: StoreId, rt: &Runtime) {

    if sepp_out {
        let sepp = scmd.value_of("sep").unwrap(); // we checked before
        let _ = writeln!(rt.stdout(), "{}", tags.join(sepp))
        writeln!(rt.stdout(), "{}", tags.join(sepp))
            .to_exit_code()
            .unwrap_or_exit();
    }

    if comm_out {
        let _ = writeln!(rt.stdout(), "{}", tags.join(", "))
        writeln!(rt.stdout(), "{}", tags.join(", "))
            .to_exit_code()
            .unwrap_or_exit();
    }

    let _ = rt.report_touched(&path).unwrap_or_exit();
    rt.report_touched(&path).unwrap_or_exit();
}

/// Get the tags which should be added from the commandline


@@ 238,7 238,6 @@ fn retrieve_tags(m: &ArgMatches, s: &'static str, v: &'static str) -> Option<Vec
         })
         .values_of(v)
         .unwrap() // enforced by clap
         .into_iter()
         .map(String::from)
         .collect())
}


@@ 286,7 285,7 @@ mod tests {
        entry.get_header().read(&"tag.values".to_owned()).map_err(Error::from)
    }

    fn tags_toml_value<'a, I: IntoIterator<Item = &'static str>>(tags: I) -> Value {
    fn tags_toml_value<I: IntoIterator<Item = &'static str>>(tags: I) -> Value {
        Value::Array(tags.into_iter().map(|s| Value::String(s.to_owned())).collect())
    }


M bin/core/imag-tag/src/ui.rs => bin/core/imag-tag/src/ui.rs +0 -1
@@ 108,7 108,6 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("id")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()

M bin/core/imag-view/src/main.rs => bin/core/imag-view/src/main.rs +9 -11
@@ 112,12 112,12 @@ fn main() {
            let viewer = rt
                .cli()
                .value_of("in")
                .ok_or_else(|| Error::from(err_msg("No viewer given")))
                .ok_or_else(|| err_msg("No viewer given"))
                .map_err_trace_exit_unwrap();

            let config = rt
                .config()
                .ok_or_else(|| Error::from(err_msg("No configuration, cannot continue")))
                .ok_or_else(|| err_msg("No configuration, cannot continue"))
                .map_err_trace_exit_unwrap();

            let query = format!("view.viewers.{}", viewer);


@@ 134,7 134,7 @@ fn main() {
            let mut handlebars = Handlebars::new();
            handlebars.register_escape_fn(::handlebars::no_escape);

            let _ = handlebars
            handlebars
                .register_template_string("template", viewer_template)
                .map_err(Error::from)
                .map_err_trace_exit_unwrap();


@@ 156,7 156,7 @@ fn main() {
            let mut elems = call.split_whitespace();
            let command_string = elems
                .next()
                .ok_or_else(|| Error::from(err_msg("No command")))
                .ok_or_else(|| err_msg("No command"))
                .map_err_trace_exit_unwrap();
            let mut cmd = Command::new(command_string);



@@ 204,9 204,8 @@ fn main() {
                .enumerate()
                .for_each(|(n, entry)| {
                    if n != 0 {
                        seperator
                            .as_ref()
                            .map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
                        if let Some(s) = seperator
                            .as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
                    }

                    if let Err(e) = viewer.view_entry(&entry, &mut outlock) {


@@ 238,9 237,8 @@ fn main() {
                .enumerate()
                .for_each(|(n, entry)| {
                    if n != 0 {
                        seperator
                            .as_ref()
                            .map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
                        if let Some(s) = seperator
                            .as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
                    }

                    if let Err(e) = viewer.view_entry(&entry, &mut outlock) {


@@ 279,7 277,7 @@ fn create_tempfile_for<'a>(entry: &FileLockEntry<'a>, view_header: bool, hide_co
        .path()
        .to_str()
        .map(String::from)
        .ok_or_else(|| Error::from(err_msg("Cannot build path")))
        .ok_or_else(|| err_msg("Cannot build path"))
        .map_err_trace_exit_unwrap();

    (tmpfile, file_path)

M bin/core/imag-view/src/ui.rs => bin/core/imag-view/src/ui.rs +0 -1
@@ 93,7 93,6 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("id")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()

M bin/core/imag/src/main.rs => bin/core/imag/src/main.rs +76 -81
@@ 102,8 102,7 @@ fn help_text(cmds: Vec<String>) -> String {
            .into_iter()
            .map(|cmd| format!("\t{}\n", cmd))
            .fold(String::new(), |s, c| {
                let s = s + c.as_str();
                s
                s + c.as_str()
            }))
}



@@ 111,14 110,14 @@ fn help_text(cmds: Vec<String>) -> String {
fn get_commands(out: &mut Stdout) -> Vec<String> {
    let mut v = match env::var("PATH") {
        Err(e) => {
            let _ = writeln!(out, "PATH error: {:?}", e)
            writeln!(out, "PATH error: {:?}", e)
                .to_exit_code()
                .unwrap_or_exit();
            exit(1)
        },

        Ok(path) => path
            .split(":")
            .split(':')
            .flat_map(|elem| {
                WalkDir::new(elem)
                    .max_depth(1)


@@ 131,7 130,7 @@ fn get_commands(out: &mut Stdout) -> Vec<String> {
                    .filter_map(|path| path
                        .file_name()
                       .to_str()
                       .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                       .and_then(|s| s.splitn(2, '-').nth(1).map(String::from))
                    )
            })
            .filter(|path| if cfg!(debug_assertions) {


@@ 185,7 184,7 @@ fn main() {
    {
        let print_help = app.clone().get_matches().subcommand_name().map(|h| h == "help").unwrap_or(false);
        if print_help {
            let _ = writeln!(out, "{}", long_help)
            writeln!(out, "{}", long_help)
                .to_exit_code()
                .unwrap_or_exit();
            exit(0)


@@ 220,7 219,7 @@ fn main() {

    if matches.is_present("version") {
        debug!("Showing version");
        let _ = writeln!(out, "imag {}", env!("CARGO_PKG_VERSION"))
        writeln!(out, "imag {}", env!("CARGO_PKG_VERSION"))
            .to_exit_code()
            .unwrap_or_exit();
        exit(0);


@@ 248,7 247,7 @@ fn main() {
            })
            .fold((), |_, line| {
                // The amount of newlines may differ depending on the subprocess
                let _ = writeln!(out, "{}", line.trim())
                writeln!(out, "{}", line.trim())
                    .to_exit_code()
                    .unwrap_or_exit();
            });


@@ 259,85 258,81 @@ fn main() {
    let aliases = match fetch_aliases(config.as_ref()) {
        Ok(aliases) => aliases,
        Err(e)      => {
            let _ = writeln!(out, "Error while fetching aliases from configuration file")
            writeln!(out, "Error while fetching aliases from configuration file")
                .to_exit_code()
                .unwrap_or_exit();
            debug!("Error = {:?}", e);
            let _ = writeln!(out, "Aborting")
            writeln!(out, "Aborting")
                .to_exit_code()
                .unwrap_or_exit();
            exit(1);
        }
    };

    // Matches any subcommand given
    match matches.subcommand() {
        (subcommand, Some(scmd)) => {
            // Get all given arguments and further subcommands to pass to
            // the imag-<> binary
            // Providing no arguments is OK, and is therefore ignored here
            let mut subcommand_args : Vec<String> = match scmd.values_of("") {
                Some(values) => values.map(String::from).collect(),
                None => Vec::new()
            };

            debug!("Processing forwarding of commandline arguments");
            forward_commandline_arguments(&matches, &mut subcommand_args);

            let subcommand = String::from(subcommand);
            let subcommand = aliases.get(&subcommand).cloned().unwrap_or(subcommand);

            debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

            // Create a Command, and pass it the gathered arguments
            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut c| c.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        debug!("imag-{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                        eprintln!("imag-{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(1));
                    }
                    debug!("Successful exit!");
                },

                Err(e) => {
                    debug!("Error calling the subcommand");
                    match e.kind() {
                        ErrorKind::NotFound => {
                            let _ = writeln!(out, "No such command: 'imag-{}'", subcommand)
                                .to_exit_code()
                                .unwrap_or_exit();
                            let _ = writeln!(out, "See 'imag --help' for available subcommands")
                                .to_exit_code()
                                .unwrap_or_exit();
                            exit(1);
                        },
                        ErrorKind::PermissionDenied => {
                            let _ = writeln!(out, "No permission to execute: 'imag-{}'", subcommand)
                                .to_exit_code()
                                .unwrap_or_exit();
                            exit(1);
                        },
                        _ => {
                            let _ = writeln!(out, "Error spawning: {:?}", e)
                                .to_exit_code()
                                .unwrap_or_exit();
                            exit(1);
                        }
    // Matches any subcommand given, except calling for example 'imag --versions', as this option
    // does not exit. There's nothing to do in such a case
    if let (subcommand, Some(scmd)) = matches.subcommand() {
        // Get all given arguments and further subcommands to pass to
        // the imag-<> binary
        // Providing no arguments is OK, and is therefore ignored here
        let mut subcommand_args : Vec<String> = match scmd.values_of("") {
            Some(values) => values.map(String::from).collect(),
            None => Vec::new()
        };

        debug!("Processing forwarding of commandline arguments");
        forward_commandline_arguments(&matches, &mut subcommand_args);

        let subcommand = String::from(subcommand);
        let subcommand = aliases.get(&subcommand).cloned().unwrap_or(subcommand);

        debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

        // Create a Command, and pass it the gathered arguments
        match Command::new(format!("imag-{}", subcommand))
            .stdin(Stdio::inherit())
            .stdout(Stdio::inherit())
            .stderr(Stdio::inherit())
            .args(&subcommand_args[..])
            .spawn()
            .and_then(|mut c| c.wait())
        {
            Ok(exit_status) => {
                if !exit_status.success() {
                    debug!("imag-{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                    eprintln!("imag-{} exited with non-zero exit code", subcommand);
                    exit(exit_status.code().unwrap_or(1));
                }
                debug!("Successful exit!");
            },

            Err(e) => {
                debug!("Error calling the subcommand");
                match e.kind() {
                    ErrorKind::NotFound => {
                        writeln!(out, "No such command: 'imag-{}'", subcommand)
                            .to_exit_code()
                            .unwrap_or_exit();
                        writeln!(out, "See 'imag --help' for available subcommands")
                            .to_exit_code()
                            .unwrap_or_exit();
                        exit(1);
                    },
                    ErrorKind::PermissionDenied => {
                        writeln!(out, "No permission to execute: 'imag-{}'", subcommand)
                            .to_exit_code()
                            .unwrap_or_exit();
                        exit(1);
                    },
                    _ => {
                        writeln!(out, "Error spawning: {:?}", e)
                            .to_exit_code()
                            .unwrap_or_exit();
                        exit(1);
                    }
                }
            }
        },
        // Calling for example 'imag --versions' will lead here, as this option does not exit.
        // There's nothing to do in such a case
        _ => {},
        }
    }
}



@@ 353,14 348,14 @@ fn fetch_aliases(config: Option<&Value>) -> Result<BTreeMap<String, String>, Str
            let mut alias_mappings = BTreeMap::new();

            for (k, v) in tbl {
                match v {
                    &Value::String(ref alias)      => {
                match *v {
                    Value::String(ref alias)      => {
                        alias_mappings.insert(alias.clone(), k.clone());
                    },
                    &Value::Array(ref aliases) => {
                    Value::Array(ref aliases) => {
                        for alias in aliases {
                            match alias {
                                &Value::String(ref s) => {
                            match *alias {
                                Value::String(ref s) => {
                                    alias_mappings.insert(s.clone(), k.clone());
                                },
                                _ => {


@@ 391,7 386,7 @@ fn forward_commandline_arguments(m: &ArgMatches, scmd: &mut Vec<String>) {
               flag = flag, val_name = val_name, matches = m, v = v);

        if m.is_present(val_name) {
            let _ = m
            m
                .value_of(val_name)
                .map(|val| {
                    debug!("Found '{:?}' = {:?}", val_name, val);

M bin/domain/imag-bookmark/src/main.rs => bin/domain/imag-bookmark/src/main.rs +24 -27
@@ 76,24 76,22 @@ fn main() {
                                    "Bookmark collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "add"        => add(&rt),
                "collection" => collection(&rt),
                "list"       => list(&rt),
                "remove"     => remove(&rt),
                other        => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            }
        });
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call {}", name);
        match name {
            "add"        => add(&rt),
            "collection" => collection(&rt),
            "list"       => list(&rt),
            "remove"     => remove(&rt),
            other        => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        }
    }
}

fn add(rt: &Runtime) {


@@ 105,13 103,13 @@ fn add(rt: &Runtime) {
        .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
        .map_err_trace_exit_unwrap();

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

    for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
        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();
        rt.report_all_touched(new_ids.into_iter()).unwrap_or_exit();
    }

    info!("Ready");


@@ 123,7 121,7 @@ fn collection(rt: &Runtime) {
    if scmd.is_present("add") { // adding a new collection
        let name = scmd.value_of("add").unwrap();
        if let Ok(id) = BookmarkCollectionStore::new(rt.store(), &name) {
            let _ = rt.report_touched(id.get_location()).unwrap_or_exit();
            rt.report_touched(id.get_location()).unwrap_or_exit();
            info!("Created: {}", name);
        } else {
            warn!("Creating collection {} failed", name);


@@ 135,7 133,7 @@ fn collection(rt: &Runtime) {
        let name = scmd.value_of("remove").unwrap();

        { // remove all links
            let _ = BookmarkCollectionStore::get(rt.store(), &name)
            BookmarkCollectionStore::get(rt.store(), &name)
                .map_err_trace_exit_unwrap()
                .ok_or_else(|| format_err!("Collection does not exist: {}", name))
                .map_err_trace_exit_unwrap()


@@ 143,7 141,7 @@ fn collection(rt: &Runtime) {
                .map_err_trace_exit_unwrap();
        }

        if let Ok(_) = BookmarkCollectionStore::delete(rt.store(), &name) {
        if BookmarkCollectionStore::delete(rt.store(), &name).is_ok() {
            info!("Deleted: {}", name);
        } else {
            warn!("Deleting collection {} failed", name);


@@ 160,13 158,12 @@ fn list(rt: &Runtime) {
        .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
        .map_err_trace_exit_unwrap();

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

    collection
        .get_links(rt.store())
        .map_dbg_str("Listing...")
        .map_err_trace_exit_unwrap()
        .into_iter()
        .enumerate()
        .for_each(|(i, link)| match link {
            Ok(link) => writeln!(rt.stdout(), "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(),


@@ 184,13 181,13 @@ fn remove(rt: &Runtime) {
        .ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
        .map_err_trace_exit_unwrap();

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

    for url in scmd.values_of("urls").unwrap() { // enforced by clap
        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();
        rt.report_all_touched(removed_links.into_iter()).unwrap_or_exit();
    }

    info!("Ready");

M bin/domain/imag-contact/src/create.rs => bin/domain/imag-contact/src/create.rs +6 -5
@@ 56,14 56,14 @@ use libimagerror::trace::trace_error;
use libimagerror::exit::ExitUnwrap;
use libimagutil::warn_result::WarnResult;

const TEMPLATE : &'static str = include_str!("../static/new-contact-template.toml");
const TEMPLATE : &str = include_str!("../static/new-contact-template.toml");

#[cfg(test)]
mod test {
    use toml::Value;
    use super::TEMPLATE;

    const TEMPLATE_WITH_DATA : &'static str = include_str!("../static/new-contact-template-test.toml");
    const TEMPLATE_WITH_DATA : &str = include_str!("../static/new-contact-template-test.toml");

    #[test]
    fn test_validity_template_toml() {


@@ 203,7 203,7 @@ pub fn create(rt: &Runtime) {
                }

                let vcard_string = write_component(&vcard);
                let _ = dest
                dest
                    .write_all(&vcard_string.as_bytes())
                    .map_err(Error::from)
                    .map_err_trace_exit_unwrap();


@@ 219,7 219,7 @@ pub fn create(rt: &Runtime) {
                .create_from_path(&location, &ref_config, &collection_name)
                .map_err_trace_exit_unwrap();

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

            info!("Created entry in store");
        } else {


@@ 232,6 232,7 @@ pub fn create(rt: &Runtime) {
    info!("Ready");
}

#[clippy::cognitive_complexity = "71"]
fn parse_toml_into_vcard(output: &mut dyn Write, input: &mut dyn Read, toml: Value, uuid: String) -> Option<Vcard> {
    let mut vcard = VcardBuilder::new().with_uid(uuid);



@@ 578,7 579,7 @@ mod test_parsing {
    use std::io::empty;

    // TODO
    const TEMPLATE : &'static str = include_str!("../static/new-contact-template-test.toml");
    const TEMPLATE : &str = include_str!("../static/new-contact-template-test.toml");

    #[test]
    fn test_template_names() {

M bin/domain/imag-contact/src/edit.rs => bin/domain/imag-contact/src/edit.rs +6 -8
@@ 73,14 73,12 @@ pub fn edit(rt: &Runtime) {
            loop {
                let res = edit_contact(&rt, &contact, &ref_config, collection_name, force_override);
                if !retry {
                    let _ = res.map_err_trace_exit_unwrap();
                } else {
                    if ask_continue(&mut input, &mut output) {
                        continue;
                    } else {
                        exit(1)
                    }
                }
                    res.map_err_trace_exit_unwrap();
                } else if ask_continue(&mut input, &mut output) {
    continue;
} else {
    exit(1)
}
            }
        });
}

M bin/domain/imag-contact/src/main.rs => bin/domain/imag-contact/src/main.rs +28 -30
@@ 95,26 95,24 @@ fn main() {
                                    build_ui);


    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "list"   => list(&rt),
                "import" => import(&rt),
                "show"   => show(&rt),
                "edit"   => edit(&rt),
                "find"   => find(&rt),
                "create" => create(&rt),
                other    => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            }
        });
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call {}", name);
        match name {
            "list"   => list(&rt),
            "import" => import(&rt),
            "show"   => show(&rt),
            "edit"   => edit(&rt),
            "find"   => find(&rt),
            "create" => create(&rt),
            other    => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        }
    }
}

fn list(rt: &Runtime) {


@@ 128,10 126,10 @@ fn list(rt: &Runtime) {
        .map_err_trace_exit_unwrap()
        .into_get_iter()
        .trace_unwrap_exit()
        .map(|fle| fle.ok_or_else(|| Error::from(err_msg("StoreId not found".to_owned()))))
        .map(|fle| fle.ok_or_else(|| err_msg("StoreId not found".to_owned())))
        .trace_unwrap_exit()
        .map(|fle| {
            let _ = rt.report_touched(fle.get_location()).unwrap_or_exit();
            rt.report_touched(fle.get_location()).unwrap_or_exit();
            fle
        })
        .map(|e| e.deser())


@@ 191,7 189,7 @@ fn import(rt: &Runtime) {
            .retrieve_from_path(&path, &ref_config, &collection_name, force_override)
            .map_err_trace_exit_unwrap();

        let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
        rt.report_touched(entry.get_location()).unwrap_or_exit();
    } else if path.is_dir() {
        for entry in WalkDir::new(path).min_depth(1).into_iter() {
            let entry = entry


@@ 205,7 203,7 @@ fn import(rt: &Runtime) {
                    .retrieve_from_path(&pb, &ref_config, &collection_name, force_override)
                    .map_err_trace_exit_unwrap();

                let _ = rt.report_touched(fle.get_location()).unwrap_or_exit();
                rt.report_touched(fle.get_location()).unwrap_or_exit();
                info!("Imported: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));
            } else {
                warn!("Ignoring non-file: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));


@@ 234,7 232,7 @@ fn show(rt: &Runtime) {
                .render("format", &data)
                .map_err(Error::from)
                .map_err_trace_exit_unwrap();
            let _ = writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit();
            writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit();
        });
}



@@ 275,7 273,7 @@ fn find(rt: &Runtime) {
                || card.fullname().iter().any(|a| str_contains_any(a, &grepstring));

            if take {
                let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                rt.report_touched(entry.get_location()).unwrap_or_exit();

                // optimization so we don't have to parse again in the next step
                Some((entry, card))


@@ 326,7 324,7 @@ fn find(rt: &Runtime) {
                    .map_err(Error::from)
                    .map_err_trace_exit_unwrap();

                let _ = writeln!(rt.stdout(), "{}", s)
                writeln!(rt.stdout(), "{}", s)
                    .to_exit_code()
                    .unwrap_or_exit();
            });


@@ 342,17 340,17 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd:
        .map(String::from)
        .unwrap_or_else(|| {
            rt.config()
                .ok_or_else(|| Error::from(err_msg("No configuration file")))
                .ok_or_else(|| err_msg("No configuration file"))
                .map_err_trace_exit_unwrap()
                .read_string(config_value_path)
                .map_err(Error::from)
                .map_err_trace_exit_unwrap()
                .ok_or_else(|| Error::from(err_msg("Configuration 'contact.list_format' does not exist")))
                .ok_or_else(|| err_msg("Configuration 'contact.list_format' does not exist"))
                .map_err_trace_exit_unwrap()
        });

    let mut hb = Handlebars::new();
    let _ = hb
    hb
        .register_template_string("format", fmt)
        .map_err(Error::from)
        .map_err_trace_exit_unwrap();

M bin/domain/imag-contact/src/util.rs => bin/domain/imag-contact/src/util.rs +9 -8
@@ 30,7 30,7 @@ use libimagrt::runtime::Runtime;
use libimagstore::store::FileLockEntry;


pub fn build_data_object_for_handlebars<'a>(i: usize, vcard: &DeserVcard) -> BTreeMap<&'static str, String> {
pub fn build_data_object_for_handlebars(i: usize, vcard: &DeserVcard) -> BTreeMap<&'static str, String> {
    let mut data = BTreeMap::new();

    let process_list = |list: &Vec<String>| {


@@ 96,21 96,22 @@ pub fn find_contact_by_hash<'a, H: AsRef<str>>(rt: &'a Runtime, hash: H)
            error!("Failed to get entry");
            exit(1)
        }))
        .filter_map(move |entry| {
        .filter(move |entry| {
            let deser = entry.deser().map_err_trace_exit_unwrap();

            if deser.uid()
            let id_starts_with_hash = deser.uid()
                .ok_or_else(|| {
                    error!("Could not get StoreId from Store::all_contacts(). This is a BUG!");
                    ::std::process::exit(1)
                })
                .unwrap() // exited above
                .starts_with(hash.as_ref())
            {
                let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                Some(entry)
                .starts_with(hash.as_ref());

            if id_starts_with_hash {
                rt.report_touched(entry.get_location()).unwrap_or_exit();
                true
            } else {
                None
                false
            }
        })
}

M bin/domain/imag-diary/src/create.rs => bin/domain/imag-diary/src/create.rs +5 -5
@@ 46,7 46,7 @@ pub fn create(rt: &Runtime) {

    let mut entry = create_entry(rt.store(), &diaryname, rt);

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

    let res = if rt.cli().subcommand_matches("create").unwrap().is_present("no-edit") {
        debug!("Not editing new diary entry");


@@ 56,7 56,7 @@ pub fn create(rt: &Runtime) {
        entry.edit_content(rt).context(err_msg("Diary edit error")).map_err(Error::from)
    };

    let _ = res.map_err_trace_exit_unwrap();
    res.map_err_trace_exit_unwrap();
    info!("Ok!");
}



@@ 126,7 126,7 @@ fn create_id_from_clispec(create: &ArgMatches, timed_type: Timed) -> NaiveDateTi
                        .map_err(|_| warn!("Could not parse minute: '{}'", s))
                        .ok()
                })
                .unwrap_or(ndt.minute());
                .unwrap_or_else(|| ndt.minute());

            ndt.with_minute(min)
                .unwrap_or_else(|| {


@@ 146,7 146,7 @@ fn create_id_from_clispec(create: &ArgMatches, timed_type: Timed) -> NaiveDateTi
                        .map_err(|_| warn!("Could not parse minute: '{}'", s))
                        .ok()
                })
                .unwrap_or(ndt.minute());
                .unwrap_or_else(|| ndt.minute());

            let sec = create
                .value_of("second")


@@ 156,7 156,7 @@ fn create_id_from_clispec(create: &ArgMatches, timed_type: Timed) -> NaiveDateTi
                        .map_err(|_| warn!("Could not parse second: '{}'", s))
                        .ok()
                })
                .unwrap_or(ndt.second());
                .unwrap_or_else(|| ndt.second());

            ndt.with_minute(min)
                .unwrap_or_else(|| {

M bin/domain/imag-diary/src/delete.rs => bin/domain/imag-diary/src/delete.rs +2 -2
@@ 67,9 67,9 @@ pub fn delete(rt: &Runtime) {
        return;
    }

    let _ = rt.report_touched(&to_del_location).unwrap_or_exit();
    rt.report_touched(&to_del_location).unwrap_or_exit();

    let _ = rt
    rt
        .store()
        .delete(to_del_location)
        .map_err_trace_exit_unwrap();

M bin/domain/imag-diary/src/list.rs => bin/domain/imag-diary/src/list.rs +1 -1
@@ 55,7 55,7 @@ pub fn list(rt: &Runtime) {
        .map(IntoStoreId::into_storeid)
        .trace_unwrap_exit()
        .for_each(|id| {
            let _ = rt.report_touched(&id).unwrap_or_exit();
            rt.report_touched(&id).unwrap_or_exit();

            if !rt.output_is_pipe() {
                writeln!(rt.stdout(), "{}", id).to_exit_code().unwrap_or_exit()

M bin/domain/imag-diary/src/main.rs => bin/domain/imag-diary/src/main.rs +17 -19
@@ 79,25 79,23 @@ fn main() {
                                    "Personal Diary/Diaries",
                                    ui::build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "diaries" => diaries(&rt),
                "create" => create(&rt),
                "delete" => delete(&rt),
                "list" => list(&rt),
                "view" => view(&rt),
                other    => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            }
        });
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call {}", name);
        match name {
            "diaries" => diaries(&rt),
            "create" => create(&rt),
            "delete" => delete(&rt),
            "list" => list(&rt),
            "view" => view(&rt),
            other    => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        }
    }
}

fn diaries(rt: &Runtime) {

M bin/domain/imag-diary/src/view.rs => bin/domain/imag-diary/src/view.rs +1 -1
@@ 45,7 45,7 @@ pub fn view(rt: &Runtime) {
        }));

    let entries = entries.map(|e| {
        let _ = rt.report_touched(e.get_location()).unwrap_or_exit();
        rt.report_touched(e.get_location()).unwrap_or_exit();

        e
    });

M bin/domain/imag-habit/src/main.rs => bin/domain/imag-habit/src/main.rs +26 -28
@@ 83,7 83,7 @@ fn main() {
                                    ui::build_ui);


    let _ = rt
    rt
        .cli()
        .subcommand_name()
        .map(|name| {


@@ 155,7 155,7 @@ fn create(rt: &Runtime) {
    debug!("Builder = {:?}", hb);

    let fle = hb.build(rt.store()).map_err_trace_exit_unwrap();
    let _   = rt.report_touched(fle.get_location()).unwrap_or_exit();
    rt.report_touched(fle.get_location()).unwrap_or_exit();
}

fn delete(rt: &Runtime) {


@@ 180,8 180,8 @@ fn delete(rt: &Runtime) {
        .trace_unwrap_exit()
        .map(|sid| (sid.clone(), rt.store().get(sid).map_err_trace_exit_unwrap())) // get the FileLockEntry
        .filter(|&(_, ref habit)| match habit { // filter for name of habit == name we look for
            &Some(ref h) => h.habit_name().map_err_trace_exit_unwrap() == name,
            &None => false,
            Some(ref h) => h.habit_name().map_err_trace_exit_unwrap() == name,
            None => false,
        })
        .filter_map(|(a, o)| o.map(|x| (a, x))) // map: (a, Option<b>) -> Option<(a, b)> -> (a, b)
        .map(|(sid, fle)| {


@@ 201,10 201,10 @@ fn delete(rt: &Runtime) {
                        if ask_bool(&q, Some(false), &mut input, &mut output)
                            .map_err_trace_exit_unwrap()
                        {
                            let _ = do_delete(id);
                            do_delete(id);
                        }
                    } else {
                        let _ = do_delete(id);
                        do_delete(id);
                    }
                };



@@ 227,10 227,10 @@ fn delete(rt: &Runtime) {
                if ask_bool(&q, Some(false), &mut input, &mut output)
                        .map_err_trace_exit_unwrap()
                {
                    let _ = do_delete_template(sid);
                    do_delete_template(sid);
                }
            } else {
                let _ = do_delete_template(sid);
                do_delete_template(sid);
            }
        })
        .collect::<Vec<_>>();


@@ 253,12 253,10 @@ fn today(rt: &Runtime, future: bool) {
            let futu = scmd.is_present("today-show-future");
            let done = scmd.is_present("today-done");
            (futu, done)
        } else if let Some(status) = rt.cli().subcommand_matches("status") {
            (true, status.is_present("status-done"))
        } else {
            if let Some(status) = rt.cli().subcommand_matches("status") {
                (true, status.is_present("status-done"))
            } else {
                (true, false)
            }
            (true, false)
        }
    };
    let today = ::chrono::offset::Local::today().naive_local();


@@ 329,7 327,7 @@ fn today(rt: &Runtime, future: bool) {

            if let Some(date) = date {
                let is_done = element
                    .instance_exists_for_date(&date)
                    .instance_exists_for_date(date)
                    .map_err_trace_exit_unwrap();

                if show_done || !is_done {


@@ 370,7 368,7 @@ fn today(rt: &Runtime, future: bool) {
                    .map_err_trace_exit_unwrap()
                    .map(|date|  {
                        let instance_exists = habit
                            .instance_exists_for_date(&date)
                            .instance_exists_for_date(date)
                            .map_err_trace_exit_unwrap();

                        debug!("instance exists for {:?} for {:?} = {:?}",


@@ 390,7 388,7 @@ fn today(rt: &Runtime, future: bool) {
                let mut list = lister_fn(&e);

                {
                    let _ = rt
                    rt
                        .report_touched(e.get_location())
                        .unwrap_or_exit();
                }


@@ 414,7 412,7 @@ fn list(rt: &Runtime) {
        let recur    = h.habit_recur_spec().map_err_trace_exit_unwrap();
        let comm     = h.habit_comment().map_err_trace_exit_unwrap();
        let (due, done) = if let Some(date) = h.next_instance_date().map_err_trace_exit_unwrap() {
            let done     = h.instance_exists_for_date(&date)
            let done     = h.instance_exists_for_date(date)
                .map(|b| if b { "x" } else { "" })
                .map(String::from)
                .map_err_trace_exit_unwrap();


@@ 438,7 436,7 @@ fn list(rt: &Runtime) {
    let mut table = Table::new();
    table.set_titles(Row::new(header));

    let _ = rt
    rt
        .store()
        .all_habit_templates()
        .map_err_trace_exit_unwrap()


@@ 460,7 458,7 @@ fn list(rt: &Runtime) {
            let mut list = lister_fn(&e);

            {
                let _ = rt.report_touched(e.get_location()).unwrap_or_exit();
                rt.report_touched(e.get_location()).unwrap_or_exit();
            }

            v.append(&mut list);


@@ 484,7 482,7 @@ fn show(rt: &Runtime) {
        use libimagutil::date::date_to_string;
        use libimaghabit::instance::HabitInstance;

        let date = date_to_string(&i.get_date().map_err_trace_exit_unwrap());
        let date = date_to_string(i.get_date().map_err_trace_exit_unwrap());
        let comm = i.get_comment(rt.store()).map_err_trace_exit_unwrap();

        vec![date, comm]


@@ 512,7 510,7 @@ fn show(rt: &Runtime) {
            let recur    = habit.habit_recur_spec().map_err_trace_exit_unwrap();
            let comm     = habit.habit_comment().map_err_trace_exit_unwrap();

            let _ = writeln!(rt.stdout(),
            writeln!(rt.stdout(),
                     "{i} - {name}\nBase      : {b},\nRecurrence: {r}\nComment   : {c}\n",
                     i    = i,
                     name = name,


@@ 544,7 542,7 @@ fn show(rt: &Runtime) {
                    let mut instances = instance_lister_fn(&rt, &e);

                    {
                        let _ = rt.report_touched(e.get_location()).unwrap_or_exit();
                        rt.report_touched(e.get_location()).unwrap_or_exit();
                    }

                    v.append(&mut instances);


@@ 574,7 572,7 @@ fn done(rt: &Runtime) {
            .filter_map(|id| get_from_store(rt.store(), id))
            .filter(|h| {
                let due = h.next_instance_date().map_err_trace_exit_unwrap();
                due.map(|d| (d == today || d < today) || scmd.is_present("allow-future"))
                due.map(|d| d <= today || scmd.is_present("allow-future"))
                    .unwrap_or(false)
            })
            .filter(|h| {


@@ 592,11 590,11 @@ fn done(rt: &Runtime) {
        let next_instance_date = r.next_instance_date().map_err_trace_exit_unwrap();
        if let Some(next) = next_instance_date {
            debug!("Creating new instance on {:?}", next);
            r.create_instance_with_date(rt.store(), &next)
            r.create_instance_with_date(rt.store(), next)
                .map_err_trace_exit_unwrap();

            info!("Done on {date}: {name}",
                  date = libimagutil::date::date_to_string(&next),
                  date = libimagutil::date::date_to_string(next),
                  name = next_instance_name);
        } else {
            info!("Ignoring: {}, because there is no due date (the habit is finised)",


@@ 604,7 602,7 @@ fn done(rt: &Runtime) {
        }

        {
            let _ = rt.report_touched(r.get_location()).unwrap_or_exit();
            rt.report_touched(r.get_location()).unwrap_or_exit();
        }

    }


@@ 612,7 610,7 @@ fn done(rt: &Runtime) {
}

/// Helper function for `Iterator::filter_map()`ing `all_habit_templates()` and `Store::get` them.
fn get_from_store<'a>(store: &'a Store, id: StoreId) -> Option<FileLockEntry<'a>> {
fn get_from_store(store: &Store, id: StoreId) -> Option<FileLockEntry<'_>> {
    match store.get(id.clone()) {
        Ok(Some(h)) => Some(h),
        Ok(None) => {


@@ 627,6 625,6 @@ fn get_from_store<'a>(store: &'a Store, id: StoreId) -> Option<FileLockEntry<'a>
}

fn date_to_string_helper(d: chrono::NaiveDate) -> String {
    libimagutil::date::date_to_string(&d)
    libimagutil::date::date_to_string(d)
}


M bin/domain/imag-log/src/main.rs => bin/domain/imag-log/src/main.rs +12 -14
@@ 104,11 104,11 @@ fn main() {

        debug!("Writing to '{}': {}", diary_name, text);

        let _ = rt
        rt
            .store()
            .new_entry_now(&diary_name)
            .map(|mut fle| {
                let _ = fle.make_log_entry().map_err_trace_exit_unwrap();
                fle.make_log_entry().map_err_trace_exit_unwrap();
                *fle.get_content_mut() = text;
                fle
            })


@@ 177,7 177,6 @@ fn show(rt: &Runtime) {
        .filter(|e| e.is_log().map_err_trace_exit_unwrap())
        .map(|entry| (entry.diary_id().map_err_trace_exit_unwrap(), entry))
        .sorted_by_key(|tpl| tpl.0.get_date_representation())
        .into_iter()
        .map(|tpl| { debug!("Found entry: {:?}", tpl.1); tpl })
        .map(|(id, entry)| {
            if let Some(wrap_limit) = do_wrap {


@@ 186,20 185,20 @@ fn show(rt: &Runtime) {
                // 10 + 4 + 2 + 2 + 2 + 2 + 6 + 4 = 32
                // plus text, which we assume to be 120 characters... lets allocate 256 bytes.
                let mut buffer = Cursor::new(Vec::with_capacity(256));
                let _ = do_write_to(&mut buffer, id, &entry, do_remove_newlines).unwrap_or_exit();
                do_write_to(&mut buffer, id, &entry, do_remove_newlines).unwrap_or_exit();
                let buffer = String::from_utf8(buffer.into_inner())
                    .map_err(Error::from)
                    .map_err_trace_exit_unwrap();

                // now lets wrap
                for line in ::textwrap::wrap(&buffer, wrap_limit).iter() {
                    let _ = writeln!(&mut output, "{}", line).to_exit_code()?;
                    writeln!(&mut output, "{}", line).to_exit_code()?;
                }
            } else {
                let _ = do_write_to(&mut output, id, &entry, do_remove_newlines).unwrap_or_exit();
                do_write_to(&mut output, id, &entry, do_remove_newlines).unwrap_or_exit();
            }

            let _ = rt
            rt
                .report_touched(entry.get_location())
                .unwrap_or_exit();
            Ok(())


@@ 214,24 213,24 @@ fn get_diary_name(rt: &Runtime) -> String {

    let cfg = rt
        .config()
        .ok_or_else(|| Error::from(err_msg("Configuration not present, cannot continue")))
        .ok_or_else(|| err_msg("Configuration not present, cannot continue"))
        .map_err_trace_exit_unwrap();

    let current_log = cfg
        .read_string("log.default")
        .map_err(Error::from)
        .map_err_trace_exit_unwrap()
        .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.default'")))
        .ok_or_else(|| err_msg("Configuration missing: 'log.default'"))
        .map_err_trace_exit_unwrap();

    if cfg
        .read("log.logs")
        .map_err(Error::from)
        .map_err_trace_exit_unwrap()
        .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.logs'")))
        .ok_or_else(|| err_msg("Configuration missing: 'log.logs'"))
        .map_err_trace_exit_unwrap()
        .as_array()
        .ok_or_else(|| Error::from(err_msg("Configuration 'log.logs' is not an Array")))
        .ok_or_else(|| err_msg("Configuration 'log.logs' is not an Array"))
        .map_err_trace_exit_unwrap()
        .iter()
        .map(|e| if !is_match!(e, &Value::String(_)) {


@@ 243,14 242,13 @@ fn get_diary_name(rt: &Runtime) -> String {
        .map(Value::as_str)
        .map(Option::unwrap) // safe by map from above
        .map(String::from)
        .filter(|log| log == &current_log)
        .next()
        .find(|log| log == &current_log)
        .is_none()
    {
        error!("'log.logs' does not contain 'log.default'");
        ::std::process::exit(1)
    } else {
        current_log.into()
        current_log
    }
}


M bin/domain/imag-mail/src/main.rs => bin/domain/imag-mail/src/main.rs +15 -17
@@ 80,23 80,21 @@ fn main() {
                                    "Mail collection tool",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "import-mail" => import_mail(&rt),
                "list"        => list(&rt),
                "mail-store"  => mail_store(&rt),
                other         => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                }
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call {}", name);
        match name {
            "import-mail" => import_mail(&rt),
            "list"        => list(&rt),
            "mail-store"  => mail_store(&rt),
            other         => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            }
        });
        }
    }
}

fn import_mail(rt: &Runtime) {


@@ 211,7 209,7 @@ fn list(rt: &Runtime) {
            ).to_exit_code().unwrap_or_exit();
        }

        let _ = rt.report_touched(m.get_location()).unwrap_or_exit();
        rt.report_touched(m.get_location()).unwrap_or_exit();
    }

    if rt.ids_from_stdin() {

M bin/domain/imag-mail/src/ui.rs => bin/domain/imag-mail/src/ui.rs +1 -2
@@ 83,12 83,11 @@ impl IdPathProvider for PathProvider {
    fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
        matches.values_of("list-id")
            .map(|v| v
                 .into_iter()
                 .map(PathBuf::from)
                 .map(|pb| pb.into_storeid())
                 .collect::<Result<Vec<_>>>()
            )
            .unwrap_or(Ok(Vec::new()))
            .unwrap_or_else(|| Ok(Vec::new()))
            .map(Some)
    }
}

M bin/domain/imag-notes/src/main.rs => bin/domain/imag-notes/src/main.rs +27 -29
@@ 74,24 74,22 @@ fn main() {
                                    "Note taking helper",
                                    build_ui);

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call: {}", name);
            match name {
                "create" => create(&rt),
                "delete" => delete(&rt),
                "edit"   => edit(&rt),
                "list"   => list(&rt),
                other    => {
                    debug!("Unknown command");
                    let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli())
                        .map_err_trace_exit_unwrap()
                        .code()
                        .map(::std::process::exit);
                },
            };
        });
    if let Some(name) = rt.cli().subcommand_name() {
        debug!("Call: {}", name);
        match name {
            "create" => create(&rt),
            "delete" => delete(&rt),
            "edit"   => edit(&rt),
            "list"   => list(&rt),
            other    => {
                debug!("Unknown command");
                let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli())
                    .map_err_trace_exit_unwrap()
                    .code()
                    .map(::std::process::exit);
            },
        };
    }
}

fn name_from_cli(rt: &Runtime, subcmd: &str) -> String {


@@ 106,17 104,17 @@ fn create(rt: &Runtime) {
        .map_err_trace_exit_unwrap();

    if rt.cli().subcommand_matches("create").unwrap().is_present("edit") {
        let _ = note
        note
            .edit_content(rt)
            .map_warn_err_str("Editing failed")
            .map_err_trace_exit_unwrap();
    }

    let _ = rt.report_touched(note.get_location()).unwrap_or_exit();
    rt.report_touched(note.get_location()).unwrap_or_exit();
}

fn delete(rt: &Runtime) {
    let _ = rt.store()
    rt.store()
        .delete_note(name_from_cli(rt, "delete"))
        .map_info_str("Ok")
        .map_err_trace_exit_unwrap();


@@ 124,17 122,17 @@ fn delete(rt: &Runtime) {

fn edit(rt: &Runtime) {
    let name = name_from_cli(rt, "edit");
    let _ = rt
    rt
        .store()
        .get_note(name.clone())
        .map_err_trace_exit_unwrap()
        .map(|mut note| {
            let _ = note
            note
                .edit_content(rt)
                .map_warn_err_str("Editing failed")
                .map_err_trace_exit_unwrap();

            let _ = rt.report_touched(note.get_location()).unwrap_or_exit();
            rt.report_touched(note.get_location()).unwrap_or_exit();
        })
        .unwrap_or_else(|| {
            error!("Cannot find note with name '{}'", name);


@@ 144,7 142,7 @@ fn edit(rt: &Runtime) {
fn list(rt: &Runtime) {
    use std::cmp::Ordering;

    let _ = rt
    rt
        .store()
        .all_notes()
        .map_err_trace_exit_unwrap()


@@ 155,17 153,17 @@ fn list(rt: &Runtime) {
            exit(1)
        }))
        .sorted_by(|note_a, note_b| if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
            return a.cmp(&b)
            a.cmp(&b)
        } else {
            return Ordering::Greater;
            Ordering::Greater
        })
        .for_each(|note| {
            let name = note.get_name().map_err_trace_exit_unwrap();
            let _ = writeln!(rt.stdout(), "{}", name)
            writeln!(rt.stdout(), "{}", name)
                .to_exit_code()
                .unwrap_or_exit();

            let _ = rt.report_touched(note.get_location()).unwrap_or_exit();
            rt.report_touched(note.get_location()).unwrap_or_exit();
        });
}


M bin/domain/imag-timetrack/src/cont.rs => bin/domain/imag-timetrack/src/cont.rs +1 -2
@@ 67,7 67,6 @@ pub fn cont(rt: &Runtime) -> i32 {
            let (k2, _) = *t2;
            Ord::cmp(&k1, &k2)
        })
        .into_iter()

        // get the last one, which should be the highest one
        .last() // -> Option<_>


@@ 88,7 87,7 @@ pub fn cont(rt: &Runtime) -> i32 {
                             .map(|_| 0)
                             .map_err_trace();

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

                         val
                     })

M bin/domain/imag-timetrack/src/day.rs => bin/domain/imag-timetrack/src/day.rs +3 -3
@@ 67,7 67,7 @@ pub fn day(rt: &Runtime) -> i32 {

        let tags = cmd
            .values_of("tags")
            .map(|ts| ts.into_iter().map(String::from).map(TimeTrackingTag::from).collect());
            .map(|ts| ts.map(String::from).map(TimeTrackingTag::from).collect::<Vec<_>>());

        let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
            start <= *dt


@@ 78,7 78,7 @@ pub fn day(rt: &Runtime) -> i32 {
        });

        let tags_filter = move |fle: &FileLockEntry| {
            match tags {
            match &tags {
                Some(ref tags) => has_one_of_tags(&tags).filter(fle),
                None => true,
            }


@@ 104,7 104,7 @@ pub fn day(rt: &Runtime) -> i32 {
            let end   = e.get_end_datetime()?;
            debug!(" -> end = {:?}", end);

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

            Ok((tag, start, end))
        })

M bin/domain/imag-timetrack/src/list.rs => bin/domain/imag-timetrack/src/list.rs +3 -3
@@ 53,7 53,7 @@ pub fn list(rt: &Runtime) -> i32 {
                        ::std::process::exit(1)
                    });

                    Some(dt.clone())
                    Some(*dt)
                },
                Err(e) => {
                    error!("Failed to calculate date from '{}': {:?}",


@@ 66,7 66,7 @@ pub fn list(rt: &Runtime) -> i32 {
                ::std::process::exit(1)
            },
            Some(Err(e)) => {
                let e = Error::from(e);
                let e = e;
                trace_error(&e);
                ::std::process::exit(1)
            }


@@ 197,7 197,7 @@ pub fn list_impl(rt: &Runtime,
                    .collect();
                tab.add_row(Row::new(cells));

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

                table_empty = false;
                Ok(tab)

M bin/domain/imag-timetrack/src/month.rs => bin/domain/imag-timetrack/src/month.rs +2 -2
@@ 82,7 82,7 @@ pub fn month(rt: &Runtime) -> i32 {

        let tags = cmd
            .values_of("tags")
            .map(|ts| ts.into_iter().map(String::from).map(TimeTrackingTag::from).collect());
            .map(|ts| ts.map(String::from).map(TimeTrackingTag::from).collect::<Vec<_>>());

        let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
            start <= *dt


@@ 119,7 119,7 @@ pub fn month(rt: &Runtime) -> i32 {
            let end   = e.get_end_datetime()?;
            debug!(" -> end = {:?}", end);

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

            Ok((tag, start, end))
        })

M bin/domain/imag-timetrack/src/shell.rs => bin/domain/imag-timetrack/src/shell.rs +3 -3
@@ 57,7 57,7 @@ pub fn shell(rt: &Runtime) -> i32 {
            mkshell(s.to_owned())
        } else {
            env::var("SHELL")
                .map(|s| mkshell(s))
                .map(mkshell)
                .map_err(|e| match e {
                    env::VarError::NotPresent => {
                        error!("No $SHELL variable in environment, cannot work!");


@@ 76,7 76,7 @@ pub fn shell(rt: &Runtime) -> i32 {
        match rt.store().create_timetracking_at(&start, tag) {
            Err(e) => trace_error(&e),
            Ok(entry) => {
                let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                rt.report_touched(entry.get_location()).unwrap_or_exit();
            }
        }
    }


@@ 101,7 101,7 @@ pub fn shell(rt: &Runtime) -> i32 {
            trace_error(&e)
        } else {
            debug!("Setting end time worked: {:?}", elem);
            let _ = rt.report_touched(elem.get_location()).unwrap_or_exit();
            rt.report_touched(elem.get_location()).unwrap_or_exit();
        });

    ::std::process::exit(exit_code)

M bin/domain/imag-timetrack/src/start.rs => bin/domain/imag-timetrack/src/start.rs +1 -1
@@ 59,7 59,7 @@ pub fn start(rt: &Runtime) -> i32 {
                    1
                },
                Ok(entry) => {
                    let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                    rt.report_touched(entry.get_location()).unwrap_or_exit();

                    acc
                }

M bin/domain/imag-timetrack/src/stop.rs => bin/domain/imag-timetrack/src/stop.rs +4 -10
@@ 60,17 60,11 @@ pub fn stop(rt: &Runtime) -> i32 {
                .get_timetrackings()
                .map_err_trace_exit_unwrap()
                .trace_unwrap()
                .filter_map(|tracking| {
                    let is_none = tracking
                .filter(|tracking| {
                    tracking
                        .get_end_datetime()
                        .map_err_trace_exit_unwrap()
                        .is_none();

                    if is_none {
                        Some(tracking)
                    } else {
                        None
                    }
                        .is_none()
                })
                .map(|t| t.get_timetrack_tag())
                .map(|r| r.map_err_trace_exit_unwrap())


@@ 99,7 93,7 @@ pub fn stop(rt: &Runtime) -> i32 {
                }
                Ok(_) => {
                    debug!("Setting end time worked: {:?}", elem);
                    let _ = rt.report_touched(elem.get_location()).unwrap_or_exit();
                    rt.report_touched(elem.get_location()).unwrap_or_exit();
                    acc
                }
            }

M bin/domain/imag-timetrack/src/track.rs => bin/domain/imag-timetrack/src/track.rs +3 -3
@@ 30,8 30,8 @@ use libimagerror::exit::ExitUnwrap;
use libimagtimetrack::tag::TimeTrackingTag;
use libimagtimetrack::store::TimeTrackStore;

const DATE_TIME_PARSE_FMT : &'static str    = "%Y-%m-%dT%H:%M:%S";
const DATE_PARSE_FMT : &'static str         = "%Y-%m-%d";
const DATE_TIME_PARSE_FMT : &str    = "%Y-%m-%dT%H:%M:%S";
const DATE_PARSE_FMT : &str         = "%Y-%m-%d";

pub fn track(rt: &Runtime) -> i32 {
    let (_, cmd) = rt.cli().subcommand();


@@ 87,7 87,7 @@ pub fn track(rt: &Runtime) -> i32 {
                1
            },
            Ok(entry) => {
                let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
                rt.report_touched(entry.get_location()).unwrap_or_exit();
                acc
            }
        })

M bin/domain/imag-timetrack/src/week.rs => bin/domain/imag-timetrack/src/week.rs +2 -2
@@ 80,7 80,7 @@ pub fn week(rt: &Runtime) -> i32 {

        let tags = cmd
            .values_of("tags")
            .map(|ts| ts.into_iter().map(String::from).map(TimeTrackingTag::from).collect());
            .map(|ts| ts.map(String::from).map(TimeTrackingTag::from).collect::<Vec<_>>());

        let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
            start <= *dt


@@ 117,7 117,7 @@ pub fn week(rt: &Runtime) -> i32 {
            let end   = e.get_end_datetime()?;
            debug!(" -> end = {:?}", end);

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

            Ok((tag, start, end))
        })

M bin/domain/imag-timetrack/src/year.rs => bin/domain/imag-timetrack/src/year.rs +2 -2
@@ 79,7 79,7 @@ pub fn year(rt: &Runtime) -> i32 {

        let tags = cmd
            .values_of("tags")
            .map(|ts| ts.into_iter().map(String::from).map(TimeTrackingTag::from).collect());
            .map(|ts| ts.map(String::from).map(TimeTrackingTag::from).collect::<Vec<_>>());

        let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
            start <= *dt


@@ 117,7 117,7 @@ pub fn year(rt: &Runtime) -> i32 {
            let end   = e.get_end_datetime()?;
            debug!(" -> end = {:?}", end);

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

            Ok((tag, start, end))
        })

M bin/domain/imag-todo/src/main.rs => bin/domain/imag-todo/src/main.rs +2 -2
@@ 97,7 97,7 @@ fn tw_hook(rt: &Runtime) {
            .import_task_from_reader(stdin)
            .map_err_trace_exit_unwrap();

        let _ = writeln!(rt.stdout(), "{}\nTask {} stored in imag", line, uuid)
        writeln!(rt.stdout(), "{}\nTask {} stored in imag", line, uuid)
            .to_exit_code()
            .unwrap_or_exit();



@@ 174,7 174,7 @@ fn list(rt: &Runtime) {
            };

            // and then print that
            let _ = writeln!(rt.stdout(), "{}", outstring).to_exit_code().unwrap_or_exit();
            writeln!(rt.stdout(), "{}", outstring).to_exit_code().unwrap_or_exit();
        });

    res.map_err_trace().ok();

M bin/domain/imag-wiki/src/main.rs => bin/domain/imag-wiki/src/main.rs +10 -10
@@ 97,7 97,7 @@ fn list(rt: &Runtime, wiki_name: &str) {
        .map_err_trace_exit_unwrap()
        .trace_unwrap_exit()
        .for_each(|id| {
            let _ = writeln!(outlock, "{}{}", prefix, id)
            writeln!(outlock, "{}{}", prefix, id)
                .to_exit_code()
                .unwrap_or_exit();
        });


@@ 114,7 114,7 @@ fn idof(rt: &Runtime, wiki_name: &str) {
    let out      = rt.stdout();
    let mut lock = out.lock();

    let _ = rt.store()
    rt.store()
        .get_wiki(wiki_name)
        .map_err_trace_exit_unwrap()
        .unwrap_or_else(|| {


@@ 159,16 159,16 @@ fn create(rt: &Runtime, wiki_name: &str) {

    if !scmd.is_present("create-noedit") {
        if scmd.is_present("create-editheader") {
            let _ = entry.edit_header_and_content(rt).map_err_trace_exit_unwrap();
            entry.edit_header_and_content(rt).map_err_trace_exit_unwrap();
        } else {
            let _ = entry.edit_content(rt).map_err_trace_exit_unwrap();
            entry.edit_content(rt).map_err_trace_exit_unwrap();
        }
    }

    let _ = entry.autolink(rt.store())
    entry.autolink(rt.store())
        .map_warn_err_str("Linking has failed. Trying to safe the entry now. Please investigate by hand if this succeeds.")
        .map_err(|e| {
            let _ = rt.store().update(&mut entry).map_err_trace_exit_unwrap();
            rt.store().update(&mut entry).map_err_trace_exit_unwrap();
            e
        })
        .map_warn_err_str("Safed entry")


@@ 183,7 183,7 @@ fn create(rt: &Runtime, wiki_name: &str) {
        writeln!(lock, "{}", id).to_exit_code().unwrap_or_exit()
    }

    let _ = rt.report_touched(&id).unwrap_or_exit();
    rt.report_touched(&id).unwrap_or_exit();
}

fn create_wiki(rt: &Runtime) {


@@ 191,7 191,7 @@ fn create_wiki(rt: &Runtime) {
    let wiki_name  = String::from(scmd.value_of("create-wiki-name").unwrap()); // safe by clap
    let (_, index) = rt.store().create_wiki(&wiki_name).map_err_trace_exit_unwrap();

    let _ = rt.report_touched(index.get_location()).unwrap_or_exit();
    rt.report_touched(index.get_location()).unwrap_or_exit();
}

fn show(rt: &Runtime, wiki_name: &str) {


@@ 249,7 249,7 @@ fn show(rt: &Runtime, wiki_name: &str) {
                .to_exit_code()
                .unwrap_or_exit();

        let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
        rt.report_touched(entry.get_location()).unwrap_or_exit();
    }
}



@@ 280,7 280,7 @@ fn delete(rt: &Runtime, wiki_name: &str) {
            .map_err_trace_exit_unwrap();
    }

    let _ = wiki
    wiki
        .delete_entry(&name)
        .map_err_trace_exit_unwrap();
}

M lib/core/libimagerror/src/trace.rs => lib/core/libimagerror/src/trace.rs +4 -4
@@ 35,19 35,19 @@ impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> {
impl<'a> Display for ImagTrace<'a, Error>
{
    fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
        let _ = writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[   0]"), self.0)?;
        writeln!(fmt, "{}: {}", Red.blink().paint("ERROR[   0]"), self.0)?;

        {
            for (i, cause) in self.0.iter_causes().enumerate() {
                let _ = writeln!(fmt,
                writeln!(fmt,
                                 "{prefix}: {error}",
                                 prefix = Red.blink().paint(format!("ERROR[{:>4}]", i + 1)),
                                 error = cause)?;
            }
        }

        let _ = writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?;
        let _ = writeln!(fmt, "{:?}", self.0.backtrace())?;
        writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?;
        writeln!(fmt, "{:?}", self.0.backtrace())?;

        Ok(())
    }

M lib/core/libimagrt/src/configuration.rs => lib/core/libimagrt/src/configuration.rs +4 -4
@@ 56,11 56,11 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result<Option<Value>> {

        env::var("HOME")
            .map(|home| gen_vars(&PathBuf::from(home), variants.iter(), &modifier))
            .unwrap_or(vec![]),
            .unwrap_or_else(|_| vec![]),

        xdg_basedir::get_data_home()
            .map(|data_dir| gen_vars(&data_dir, variants.iter(), &modifier))
            .unwrap_or(vec![]),
            .unwrap_or_else(|_| vec![]),
    ];

    let config = vals


@@ 121,10 121,10 @@ pub fn override_config(val: &mut Value, v: Vec<String>) -> Result<()> {
        .map(|(k, v)| {
            let value = val.read_mut(&k)
                .context(EM::TomlQueryError)?
                .ok_or_else(|| Error::from(err_msg("No config value there, cannot override.")))?;
                .ok_or_else(|| err_msg("No config value there, cannot override."))?;

            let new_value = into_value(value, v)
                .ok_or_else(|| Error::from(err_msg("Config override type not matching")))?;
                .ok_or_else(|| err_msg("Config override type not matching"))?;

            info!("Successfully overridden: {} = {}", k, new_value);
            *value = new_value;

M lib/core/libimagrt/src/logger.rs => lib/core/libimagrt/src/logger.rs +24 -22
@@ 90,18 90,18 @@ impl ImagLogger {

        {
            use self::log_lvl_aggregate::*;
            let _ = aggregate::<Trace>(&mut handlebars, config, "TRACE")?;
            let _ = aggregate::<Debug>(&mut handlebars, config, "DEBUG")?;
            let _ = aggregate::<Info>(&mut handlebars, config, "INFO")?;
            let _ = aggregate::<Warn>(&mut handlebars, config, "WARN")?;
            let _ = aggregate::<Error>(&mut handlebars, config, "ERROR")?;
            aggregate::<Trace>(&mut handlebars, config, "TRACE")?;
            aggregate::<Debug>(&mut handlebars, config, "DEBUG")?;
            aggregate::<Info>(&mut handlebars, config, "INFO")?;
            aggregate::<Warn>(&mut handlebars, config, "WARN")?;
            aggregate::<Error>(&mut handlebars, config, "ERROR")?;
        }

        Ok(ImagLogger {
            global_loglevel     : aggregate_global_loglevel(matches, config)?,
            global_destinations : aggregate_global_destinations(config)?,
            module_settings     : aggregate_module_settings(matches, config)?,
            handlebars          : handlebars,
            handlebars,
        })
    }



@@ 138,17 138,17 @@ impl Log for ImagLogger {
            .render(&format!("{}", record.level()), &data)
            .unwrap_or_else(|e| format!("Failed rendering logging data: {:?}\n", e));

        let log_to_destination = |d: &LogDestination| match d {
            &LogDestination::Stderr => {
                let _ = write!(stderr(), "{}\n", logtext);
        let log_to_destination = |d: &LogDestination| match *d {
            LogDestination::Stderr => {
                let _ = writeln!(stderr(), "{}", logtext);
            },
            &LogDestination::File(ref arc_mutex_logdest) => {
            LogDestination::File(ref arc_mutex_logdest) => {
                // if there is an error in the lock, we cannot do anything. So we ignore it here.
                let _ = arc_mutex_logdest
                    .deref()
                    .lock()
                    .map(|mut logdest| {
                        write!(logdest, "{}\n", logtext)
                        writeln!(logdest, "{}", logtext)
                    });
            }
        };


@@ 169,14 169,16 @@ impl Log for ImagLogger {
                    module_setting.level.unwrap_or(self.global_loglevel) >= record.level();

                if set {
                    module_setting.destinations.as_ref().map(|destinations| for d in destinations {
                        // If there's an error, we cannot do anything, can we?
                        let _ = log_to_destination(&d);
                    });
                    if let Some(destinations) = &module_setting.destinations {
                        for d in destinations {
                            // If there's an error, we cannot do anything, can we?
                            log_to_destination(&d);
                        }
                    }

                    for d in self.global_destinations.iter() {
                        // If there's an error, we cannot do anything, can we?
                        let _ = log_to_destination(&d);
                        log_to_destination(&d);
                    }
                }
            })


@@ 185,7 187,7 @@ impl Log for ImagLogger {
                // Yes, we log
                for d in self.global_destinations.iter() {
                    // If there's an error, we cannot do anything, can we?
                    let _ = log_to_destination(&d);
                    log_to_destination(&d);
                }
            }
        });


@@ 199,7 201,7 @@ fn match_log_level_str(s: &str) -> Result<Level> {
        "info"  => Ok(Level::Info),
        "warn"  => Ok(Level::Warn),
        "error" => Ok(Level::Error),
        lvl     => return Err(format_err!("Invalid logging level: {}", lvl)),
        lvl     => Err(format_err!("Invalid logging level: {}", lvl)),
    }
}



@@ 225,7 227,7 @@ fn aggregate_global_loglevel(matches: &ArgMatches, config: Option<&Value>) -> Re
            .read_string("imag.logging.level")
            .map_err(Error::from)
            .context(EM::TomlQueryError)?
            .ok_or(err_msg("Global log level config missing"))
            .ok_or_else(|| err_msg("Global log level config missing"))
            .and_then(|s| match_log_level_str(&s))?;

        if let Some(cli_loglevel) = get_arg_loglevel(matches)? {


@@ 262,7 264,7 @@ fn translate_destination(raw: &str) -> Result<LogDestination> {
}


fn translate_destinations(raw: &Vec<Value>) -> Result<Vec<LogDestination>> {
fn translate_destinations(raw: &[Value]) -> Result<Vec<LogDestination>> {
    raw.iter()
        .map(|val| {
            val.as_str()


@@ 287,9 289,9 @@ fn aggregate_global_destinations(config: Option<&Value>)
            .as_array()
            .ok_or_else(|| {
                let msg = "Type error at 'imag.logging.destinations', expected 'Array'";
                Error::from(err_msg(msg))
                err_msg(msg)
            })
            .and_then(translate_destinations),
            .and_then(|val| translate_destinations(val)),
    }
}


M lib/core/libimagrt/src/runtime.rs => lib/core/libimagrt/src/runtime.rs +7 -7
@@ 153,8 153,8 @@ impl<'a> Runtime<'a> {
        store_result.map(|store| Runtime {
            cli_matches: matches,
            configuration: config,
            rtp: rtp,
            store: store,
            rtp,
            store,

            has_output_pipe,
            has_input_pipe,


@@ 381,14 381,14 @@ impl<'a> Runtime<'a> {
            .map(String::from)
            .ok_or_else(|| {
                self.config()
                    .ok_or_else(|| Error::from(err_msg("No Configuration!")))
                    .ok_or_else(|| err_msg("No Configuration!"))
                    .and_then(|v| match v.read("rt.editor")? {
                        Some(&Value::String(ref s)) => Ok(Some(s.clone())),
                        Some(_) => Err(Error::from(err_msg("Type error at 'rt.editor', expected 'String'"))),
                        Some(_) => Err(err_msg("Type error at 'rt.editor', expected 'String'")),
                        None    => Ok(None),
                    })
            })
            .or(env::var("EDITOR"))
            .or_else(|_| env::var("EDITOR"))
            .map_err(|_| Error::from(EM::IO))
            .map_dbg(|s| format!("Editing with '{}'", s))
            .and_then(|s| {


@@ 617,13 617,13 @@ fn get_override_specs(matches: &ArgMatches) -> Vec<String> {
        .map(|values| {
             values
             .filter(|s| {
                 let b = s.contains("=");
                 let b = s.contains('=');
                 if !b { warn!("override '{}' does not contain '=' - will be ignored!", s); }
                 b
             })
             .map(String::from)
             .collect()
        })
        .unwrap_or(vec![])
        .unwrap_or_else(|| vec![])
}


M lib/core/libimagstore/src/file_abstraction/fs.rs => lib/core/libimagstore/src/file_abstraction/fs.rs +4 -4
@@ 108,7 108,7 @@ impl FileAbstraction for FSFileAbstraction {
        if let Some(p) = to.parent() {
            if !p.exists() {
                debug!("Creating: {:?}", p);
                let _ = create_dir_all(&p).context(EM::DirNotCreated)?;
                create_dir_all(&p).context(EM::DirNotCreated)?;
            }
        } else {
            debug!("Failed to find parent. This looks like it will fail now");


@@ 204,8 204,8 @@ impl PathIterBuilder for WalkDirPathIterBuilder {
fn open_file<A: AsRef<Path>>(p: A) -> ::std::io::Result<Option<File>> {
    match OpenOptions::new().write(true).read(true).open(p) {
        Err(e) => match e.kind() {
            ::std::io::ErrorKind::NotFound => return Ok(None),
            _ => return Err(e),
            ::std::io::ErrorKind::NotFound => Ok(None),
            _ => Err(e),
        },
        Ok(file) => Ok(Some(file))
    }


@@ 216,7 216,7 @@ fn create_file<A: AsRef<Path>>(p: A) -> ::std::io::Result<File> {
        trace!("'{}' is directory = {}", parent.display(), parent.is_dir());
        if !parent.is_dir() {
            trace!("Implicitely creating directory: {:?}", parent);
            let _ = create_dir_all(parent)?;
            create_dir_all(parent)?;
        }
    }
    OpenOptions::new().write(true).read(true).create(true).open(p)

M lib/core/libimagstore/src/file_abstraction/inmemory.rs => lib/core/libimagstore/src/file_abstraction/inmemory.rs +7 -11
@@ 79,14 79,11 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance {
    }

    fn write_file_content(&mut self, buf: &Entry) -> Result<()> {
        match *self {
            InMemoryFileAbstractionInstance { ref absent_path, .. } => {
                let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed");
                let backend = mtx.get_mut();
                let _ = backend.insert(absent_path.clone(), buf.clone());
                return Ok(());
            },
        };
        let absent_path = &self.absent_path;
        let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed");
        let backend = mtx.get_mut();
        let _ = backend.insert(absent_path.clone(), buf.clone());
        Ok(())
    }
}



@@ 101,12 98,11 @@ impl InMemoryFileAbstraction {
        &self.virtual_filesystem
    }

    fn backend_cloned<'a>(&'a self) -> Result<HashMap<PathBuf, Entry>> {
    fn backend_cloned(&self) -> Result<HashMap<PathBuf, Entry>> {
        self.virtual_filesystem
            .lock()
            .map_err(|_| Error::from(EM::LockError))
            .map(|mtx| mtx.deref().borrow().clone())
            .into()
    }

}


@@ 172,7 168,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
        self.backend_cloned().map(Drain::new)
    }

    fn fill<'a>(&'a mut self, mut d: Drain) -> Result<()> {
    fn fill(&mut self, mut d: Drain) -> Result<()> {
        debug!("Draining into : {:?}", self);
        let mut mtx = self.backend()
            .lock()

M lib/core/libimagstore/src/file_abstraction/mod.rs => lib/core/libimagstore/src/file_abstraction/mod.rs +2 -2
@@ 46,7 46,7 @@ pub(crate) trait FileAbstraction : Debug {
    fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance>;

    fn drain(&self) -> Result<Drain>;
    fn fill<'a>(&'a mut self, d: Drain) -> Result<()>;
    fn fill(&mut self, d: Drain) -> Result<()>;

    fn pathes_recursively<'a>(&self, basepath: PathBuf, storepath: &'a PathBuf, backend: Arc<dyn FileAbstraction>) -> Result<PathIterator<'a>>;
}


@@ 74,7 74,7 @@ impl Drain {
        Drain::new(HashMap::new())
    }

    pub fn iter<'a>(&'a mut self) -> DrainIter<'a> {
    pub fn iter(&mut self) -> DrainIter<'_> {
        DrainIter(self.0.drain())
    }


M lib/core/libimagstore/src/store.rs => lib/core/libimagstore/src/store.rs +24 -27
@@ 148,7 148,6 @@ pub struct Store {
}

impl Store {

    /// Create a new Store object
    ///
    /// This opens a Store in `location`. The store_config is used to check whether creating the


@@ 210,7 209,7 @@ impl Store {
        let store = Store {
            location: location.clone(),
            entries: Arc::new(RwLock::new(HashMap::new())),
            backend: backend,
            backend,
        };

        debug!("Store building succeeded");


@@ 491,7 490,7 @@ impl Store {
        }

        debug!("Seems like {:?} is on the FS", pb);
        let _ = self
        self
            .backend
            .remove_file(&pb)
            .context(EM::FileError)


@@ 608,7 607,7 @@ impl Store {
            }
            debug!("New entry does not yet exist on filesystem. Good.");

            let _ = self
            self
                .backend
                .rename(&old_id_pb, &new_id_pb)
                .context({


@@ 621,12 620,14 @@ impl Store {

            // assert enforced through check hsmap.contains_key(&new_id) above.
            // Should therefor never fail
            assert!(hsmap
                    .remove(&old_id)
                    .and_then(|mut entry| {
                        entry.id = new_id.clone().into();
                        hsmap.insert(new_id.clone().into(), entry)
                    }).is_none())
            let hsmap_does_not_have_key = hsmap
                .remove(&old_id)
                .and_then(|mut entry| {
                    entry.id = new_id.clone();
                    hsmap.insert(new_id.clone(), entry)
                })
                .is_none();
            assert!(hsmap_does_not_have_key);
        }

        debug!("Moved");


@@ 642,7 643,7 @@ impl Store {
    }

    /// Check whether the store has the Entry pointed to by the StoreId `id`
    pub fn exists<'a>(&'a self, id: StoreId) -> Result<bool> {
    pub fn exists(&self, id: StoreId) -> Result<bool> {
        let cache_has_entry = |id: &StoreId|
            self.entries
                .read()


@@ 660,7 661,6 @@ impl Store {
    pub fn path(&self) -> &PathBuf {
        &self.location
    }

}

impl Debug for Store {


@@ 986,13 986,13 @@ mod test {
        assert!(has_imag_version_in_main_section(&Value::Table(map)).is_err());
    }

    static TEST_ENTRY : &'static str = "---
    static TEST_ENTRY : &str = "---
[imag]
version = '0.0.3'
---
Hai";

    static TEST_ENTRY_TNL : &'static str = "---
    static TEST_ENTRY_TNL : &str = "---
[imag]
version = '0.0.3'
---


@@ 1129,14 1129,12 @@ mod store_tests {

        for n in 1..100 {
            let s = format!("test-{}", n % 50);
            store.create(PathBuf::from(s.clone()))
                .ok()
                .map(|entry| {
                    assert!(entry.verify().is_ok());
                    let loc = entry.get_location().clone().with_base(store.path()).into_pathbuf().unwrap();
                    assert!(loc.starts_with("/"));
                    assert!(loc.ends_with(s));
                });
            if let Ok(entry) = store.create(PathBuf::from(s.clone())) {
                assert!(entry.verify().is_ok());
                let loc = entry.get_location().clone().with_base(store.path()).into_pathbuf().unwrap();
                assert!(loc.starts_with("/"));
                assert!(loc.ends_with(s));
            }
        }
    }



@@ 1176,8 1174,8 @@ mod store_tests {

        for n in 1..100 {
            match store.get(PathBuf::from(format!("test-{}", n))) {
                Ok(None) => assert!(true),
                _        => assert!(false),
                Ok(None) => {},
                _        => panic!(),
            }
        }
    }


@@ 1188,8 1186,8 @@ mod store_tests {

        for n in 1..100 {
            match store.delete(PathBuf::from(format!("test-{}", n))) {
                Err(_) => assert!(true),
                _      => assert!(false),
                Err(_) => {},
                _      => panic!(),
            }
        }
    }


@@ 1237,4 1235,3 @@ mod store_tests {
    }

}


M lib/core/libimagstore/src/storeid.rs => lib/core/libimagstore/src/storeid.rs +2 -2
@@ 59,7 59,7 @@ impl StoreId {
        }
    }

    pub(crate) fn with_base<'a>(self, base: &'a PathBuf) -> StoreIdWithBase<'a> {
    pub(crate) fn with_base(self, base: &PathBuf) -> StoreIdWithBase<'_> {
        StoreIdWithBase(base, self.0)
    }



@@ 265,7 265,7 @@ impl StoreIdIterator {
        StoreIdIterator { iter }
    }

    pub fn with_store<'a>(self, store: &'a Store) -> StoreIdIteratorWithStore<'a> {
    pub fn with_store(self, store: &Store) -> StoreIdIteratorWithStore<'_> {
        StoreIdIteratorWithStore(self, store)
    }


M lib/core/libimagstore/src/util.rs => lib/core/libimagstore/src/util.rs +3 -3
@@ 55,11 55,11 @@ pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> {
            header_consumed = true;
            // do not further process the line
        } else if !header_consumed {
            let _ = writeln!(header, "{}", line).context(EM::FormatError)?;
            writeln!(header, "{}", line).context(EM::FormatError)?;
        } else if iter.peek().is_some() {
            let _ = writeln!(content, "{}", line).context(EM::FormatError)?;
            writeln!(content, "{}", line).context(EM::FormatError)?;
        } else {
            let _ = write!(content, "{}", line).context(EM::FormatError)?;
            write!(content, "{}", line).context(EM::FormatError)?;
        }
    }


M lib/domain/libimagbookmark/src/collection.rs => lib/domain/libimagbookmark/src/collection.rs +3 -2
@@ 51,6 51,7 @@ pub trait BookmarkCollectionStore<'a> {

impl<'a> BookmarkCollectionStore<'a> for Store {

    #[allow(clippy::new_ret_no_self)]
    fn new(&'a self, name: &str) -> Result<FileLockEntry<'a>> {
        crate::module_path::new_id(name)
            .and_then(|id| self.create(id)


@@ 94,6 95,7 @@ impl BookmarkCollection for Entry {
        self.get_urls(store)
    }

    #[allow(clippy::redundant_closure)]
    fn link_entries(&self) -> Result<Vec<StoreLink>> {
        use libimagentryurl::util::is_external_link_storeid;
        self.links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())


@@ 119,7 121,6 @@ impl BookmarkCollection for Entry {
pub mod iter {
    use crate::link::Link;
    use failure::Fallible as Result;
    use failure::Error;
    use regex::Regex;

    use libimagentryurl::iter::UrlIter;


@@ 162,7 163,7 @@ pub mod iter {
            loop {
                let n = match self.0.next() {
                    Some(Ok(n))  => n,
                    Some(Err(e)) => return Some(Err(Error::from(e))),
                    Some(Err(e)) => return Some(Err(e)),
                    None         => return None,
                };


M lib/domain/libimagcontact/src/store.rs => lib/domain/libimagcontact/src/store.rs +1 -1
@@ 157,7 157,7 @@ fn prepare_fetching_from_store(buf: &str) -> Result<(StoreId, Value)> {
    debug!("Parsed: {:?}", vcard);

    let uid = vcard.uid()
        .ok_or_else(|| Error::from(format_err!("UID Missing: {}", buf.to_string())))?;
        .ok_or_else(|| format_err!("UID Missing: {}", buf.to_string()))?;

    let value = { // dirty ugly hack
        let serialized = DeserVcard::from(vcard);

M lib/domain/libimagdiary/src/diary.rs => lib/domain/libimagdiary/src/diary.rs +2 -3
@@ 68,7 68,7 @@ impl Diary for Store {
        let id  = DiaryId::new(String::from(diary_name), ndt.year(), ndt.month(), ndt.day(), 0, 0, 0);

        let mut entry = self.retrieve(id)?;
        let _         = entry.set_isflag::<IsDiaryEntry>()?;
        entry.set_isflag::<IsDiaryEntry>()?;
        Ok(entry)
    }



@@ 88,7 88,7 @@ impl Diary for Store {
                               ndt.second());

        let mut entry = self.retrieve(id)?;
        let _         = entry.set_isflag::<IsDiaryEntry>()?;
        entry.set_isflag::<IsDiaryEntry>()?;
        Ok(entry)
    }



@@ 131,7 131,6 @@ impl Diary for Store {
                            },
                        }
                    })
                    .into_iter()
                    .rev()
                    .next()
            }

M lib/domain/libimagdiary/src/diaryid.rs => lib/domain/libimagdiary/src/diaryid.rs +5 -5
@@ 49,7 49,7 @@ impl DiaryId {

    pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32, sec: u32) -> DiaryId {
        DiaryId {
            name: name,
            name,
            year: y,
            month: m,
            day: d,


@@ 202,7 202,7 @@ fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str> {
        Component::Normal(s) => Some(s),
        _ => None,
    }.and_then(|s| s.to_str())
    .ok_or_else(|| Error::from(err_msg("ID Parse error")))
    .ok_or_else(|| err_msg("ID Parse error"))
}

impl FromStoreId for DiaryId {


@@ 215,7 215,7 @@ impl FromStoreId for DiaryId {

        fn next_component<'a>(components: &'a mut Rev<Components>) -> Result<&'a str> {
            components.next()
                .ok_or_else(|| Error::from(err_msg("ID parse error")))
                .ok_or_else(|| err_msg("ID parse error"))
                .and_then(component_to_str)
        }



@@ 223,7 223,7 @@ impl FromStoreId for DiaryId {
        trace!("Found components: {:?}", cmps);

        let (hour, minute, second) = next_component(&mut cmps).and_then(|time| {
            let mut time = time.split(":");
            let mut time = time.split(':');
            let hour     = time.next().and_then(|s| FromStr::from_str(s).ok());
            let minute   = time.next().and_then(|s| FromStr::from_str(s).ok());
            let second   = time.next().and_then(|s| FromStr::from_str(s).ok());


@@ 235,7 235,7 @@ impl FromStoreId for DiaryId {

            match (hour, minute, second) {
                (Some(h), Some(m), Some(s)) => Ok((h, m, s)),
                _ => return Err(Error::from(err_msg("ID Parse error"))),
                _ => Err(err_msg("ID Parse error")),
            }
        })?;


M lib/domain/libimagdiary/src/iter.rs => lib/domain/libimagdiary/src/iter.rs +4 -4
@@ 27,7 27,7 @@ use libimagstore::storeid::StoreId;

use crate::is_in_diary::IsInDiary;
use failure::Fallible as Result;
use failure::Error;

use failure::err_msg;

/// A iterator for iterating over diary entries


@@ 54,7 54,7 @@ impl DiaryEntryIterator {
    pub fn new(diaryname: String, iter: StoreIdIterator) -> DiaryEntryIterator {
        DiaryEntryIterator {
            name: diaryname,
            iter: iter,
            iter,

            year: None,
            month: None,


@@ 149,8 149,8 @@ impl Iterator for DiaryNameIterator {
                        .and_then(|s| {
                            s.split("diary/")
                                .nth(1)
                                .and_then(|n| n.split("/").nth(0).map(String::from))
                                .ok_or_else(|| Error::from(err_msg("Error finding diary name")))
                                .and_then(|n| n.split('/').nth(0).map(String::from))
                                .ok_or_else(|| err_msg("Error finding diary name"))
                        }));
                },
            }

M lib/domain/libimagdiary/src/viewer.rs => lib/domain/libimagdiary/src/viewer.rs +1 -1
@@ 82,7 82,7 @@ impl Viewer for DiaryViewer {

        for (id, entry) in entries.into_iter() {
            writeln!(sink, "{} :\n", id)?;
            let _ = self.0.view_entry(entry.deref(), sink)?;
            self.0.view_entry(entry.deref(), sink)?;
            writeln!(sink, "\n---\n")?;
        }


M lib/domain/libimaghabit/src/habit.rs => lib/domain/libimaghabit/src/habit.rs +26 -26
@@ 55,7 55,7 @@ pub trait HabitTemplate : Sized {
    ///
    /// It uses `Store::retrieve()` underneath. So if there is already an instance for the day
    /// passed, this will simply return the instance.
    fn create_instance_with_date<'a>(&mut self, store: &'a Store, date: &NaiveDate)
    fn create_instance_with_date<'a>(&mut self, store: &'a Store, date: NaiveDate)
        -> Result<FileLockEntry<'a>>;

    /// Shortcut for calling `Self::create_instance_with_date()` with an instance of


@@ 63,7 63,7 @@ pub trait HabitTemplate : Sized {
    fn create_instance_today<'a>(&mut self, store: &'a Store) -> Result<FileLockEntry<'a>>;

    /// Same as `HabitTemplate::create_instance_with_date()` but uses `Store::retrieve` internally.
    fn retrieve_instance_with_date<'a>(&mut self, store: &'a Store, date: &NaiveDate)
    fn retrieve_instance_with_date<'a>(&mut self, store: &'a Store, date: NaiveDate)
        -> Result<FileLockEntry<'a>>;

    /// Same as `HabitTemplate::create_instance_today()` but uses `Store::retrieve` internally.


@@ 87,17 87,17 @@ pub trait HabitTemplate : Sized {
    fn habit_comment(&self) -> Result<String>;
    fn habit_until_date(&self) -> Result<Option<String>>;

    fn instance_exists_for_date(&self, date: &NaiveDate) -> Result<bool>;
    fn instance_exists_for_date(&self, date: NaiveDate) -> Result<bool>;

    /// Create a StoreId for a habit name and a date the habit should be instantiated for
    fn instance_id_for(habit_name: &String, habit_date: &NaiveDate) -> Result<StoreId>;
    fn instance_id_for(habit_name: &str, habit_date: NaiveDate) -> Result<StoreId>;
}

provide_kindflag_path!(pub IsHabitTemplate, "habit.template.is_habit_template");

impl HabitTemplate for Entry {

    fn create_instance_with_date<'a>(&mut self, store: &'a Store, date: &NaiveDate) -> Result<FileLockEntry<'a>> {
    fn create_instance_with_date<'a>(&mut self, store: &'a Store, date: NaiveDate) -> Result<FileLockEntry<'a>> {
        let name    = self.habit_name()?;
        let date    = date_to_string(date);
        let id      = instance_id_for_name_and_datestr(&name, &date)?;


@@ 108,10 108,10 @@ impl HabitTemplate for Entry {
    }

    fn create_instance_today<'a>(&mut self, store: &'a Store) -> Result<FileLockEntry<'a>> {
        self.create_instance_with_date(store, &Local::today().naive_local())
        self.create_instance_with_date(store, Local::today().naive_local())
    }

    fn retrieve_instance_with_date<'a>(&mut self, store: &'a Store, date: &NaiveDate) -> Result<FileLockEntry<'a>> {
    fn retrieve_instance_with_date<'a>(&mut self, store: &'a Store, date: NaiveDate) -> Result<FileLockEntry<'a>> {
        let name    = self.habit_name()?;
        let date    = date_to_string(date);
        let id      = instance_id_for_name_and_datestr(&name, &date)?;


@@ 122,7 122,7 @@ impl HabitTemplate for Entry {
    }

    fn retrieve_instance_today<'a>(&mut self, store: &'a Store) -> Result<FileLockEntry<'a>> {
        self.retrieve_instance_with_date(store, &Local::today().naive_local())
        self.retrieve_instance_with_date(store, Local::today().naive_local())
    }

    fn linked_instances(&self) -> Result<HabitInstanceStoreIdIterator> {


@@ 160,11 160,11 @@ impl HabitTemplate for Entry {
        debug!("Increment is {:?}", increment);

        let until = self.habit_until_date()?.map(|s| -> Result<_> {
            r#try!(date_from_s(s))
            date_from_s(s)?
                .calculate()?
                .get_moment()
                .map(Clone::clone)
                .ok_or_else(|| Error::from(err_msg("until-date seems to have non-date value")))
                .ok_or_else(|| err_msg("until-date seems to have non-date value"))
        });

        debug!("Until-Date is {:?}", basedate);


@@ 177,7 177,7 @@ impl HabitTemplate for Entry {
                if ndt >= base {
                    debug!("-> {:?} >= {:?}", ndt, base);
                    if let Some(u) = until {
                        if ndt > &(u?) {
                        if *ndt > u? {
                            return Ok(None);
                        } else {
                            return Ok(Some(ndt.date()));


@@ 233,7 233,7 @@ impl HabitTemplate for Entry {
            .map(|os| os.map(String::from))
    }

    fn instance_exists_for_date(&self, date: &NaiveDate) -> Result<bool> {
    fn instance_exists_for_date(&self, date: NaiveDate) -> Result<bool> {
        let name = self.habit_name()?;
        let date = date_to_string(date);



@@ 246,16 246,16 @@ impl HabitTemplate for Entry {
            }
        }

        return Ok(false);
        Ok(false)
    }

    fn instance_id_for(habit_name: &String, habit_date: &NaiveDate) -> Result<StoreId> {
    fn instance_id_for(habit_name: &str, habit_date: NaiveDate) -> Result<StoreId> {
        instance_id_for_name_and_datestr(habit_name, &date_to_string(habit_date))
    }

}

fn instance_id_for_name_and_datestr(habit_name: &String, habit_date: &String) -> Result<StoreId> {
fn instance_id_for_name_and_datestr(habit_name: &str, habit_date: &str) -> Result<StoreId> {
    crate::module_path::new_id(format!("instance/{}-{}", habit_name, habit_date))
        .context(format_err!("Failed building ID for instance: habit name = {}, habit date = {}", habit_name, habit_date))
        .map_err(Error::from)


@@ 318,7 318,7 @@ pub mod builder {
        pub fn build<'a>(self, store: &'a Store) -> Result<FileLockEntry<'a>> {
            #[inline]
            fn mkerr(s: &'static str) -> Error {
                Error::from(format_err!("Habit builder missing: {}", s))
                format_err!("Habit builder missing: {}", s)
            }

            let name = self.name


@@ 336,7 336,7 @@ pub mod builder {
            if let Some(until) = self.untildate {
                debug!("Success: Until-Date present");
                if dateobj > until {
                    let e = Error::from(err_msg("Habit builder logic error: until-date before start date"));
                    let e = err_msg("Habit builder logic error: until-date before start date");
                    return Err(e);
                }
            }


@@ 345,16 345,16 @@ pub mod builder {
                debug!("Kairos failed: {:?}", e);
                return Err(e)
            }
            let date      = date_to_string(&dateobj);
            let date      = date_to_string(dateobj);
            debug!("Success: Date valid");

            let comment   = self.comment.unwrap_or_else(|| String::new());
            let sid       = r#try!(build_habit_template_sid(&name));
            let comment   = self.comment.unwrap_or_else(String::new);
            let sid       = build_habit_template_sid(&name)?;

            debug!("Creating entry in store for: {:?}", sid);
            let mut entry = r#try!(store.create(sid));
            let mut entry = store.create(sid)?;

            let _ = entry.set_isflag::<IsHabitTemplate>()?;
            entry.set_isflag::<IsHabitTemplate>()?;
            {
                let h = entry.get_header_mut();
                let _ = h.insert("habit.template.name", Value::String(name))?;


@@ 364,8 364,8 @@ pub mod builder {
            }

            if let Some(until) = self.untildate {
                let until = date_to_string(&until);
                r#try!(entry.get_header_mut().insert("habit.template.until", Value::String(until)));
                let until = date_to_string(until);
                entry.get_header_mut().insert("habit.template.until", Value::String(until))?;
            }

            debug!("Success: Created entry in store and set headers");


@@ 387,7 387,7 @@ pub mod builder {
    }

    /// Buld a StoreId for a Habit from a date object and a name of a habit
    fn build_habit_template_sid(name: &String) -> Result<StoreId> {
    fn build_habit_template_sid(name: &str) -> Result<StoreId> {
        crate::module_path::new_id(format!("template/{}", name)).map_err(From::from)
    }



@@ 400,7 400,7 @@ fn postprocess_instance<'a>(mut entry: FileLockEntry<'a>,
    -> Result<FileLockEntry<'a>>
{
    {
        let _   = entry.set_isflag::<IsHabitInstance>()?;
        entry.set_isflag::<IsHabitInstance>()?;
        let hdr = entry.get_header_mut();
        let _   = hdr.insert("habit.instance.name",    Value::String(name))?;
        let _   = hdr.insert("habit.instance.date",    Value::String(date))?;

M lib/domain/libimaghabit/src/instance.rs => lib/domain/libimaghabit/src/instance.rs +2 -2
@@ 45,7 45,7 @@ pub trait HabitInstance {
    fn is_habit_instance(&self) -> Result<bool>;

    fn get_date(&self) -> Result<NaiveDate>;
    fn set_date(&mut self, n: &NaiveDate) -> Result<()>;
    fn set_date(&mut self, n: NaiveDate) -> Result<()>;
    fn get_comment(&self, store: &Store) -> Result<String>;
    fn get_template_name(&self) -> Result<String>;
}


@@ 63,7 63,7 @@ impl HabitInstance for Entry {
        get_string_header_from_entry(self, "habit.instance.date").and_then(date_from_string)
    }

    fn set_date(&mut self, n: &NaiveDate) -> Result<()> {
    fn set_date(&mut self, n: NaiveDate) -> Result<()> {
        use libimagutil::date::date_to_string;
        // Using `set` here because when creating the entry, these headers should be made present.
        self.get_header_mut()

M lib/domain/libimagmail/src/config.rs => lib/domain/libimagmail/src/config.rs +5 -10
@@ 51,8 51,7 @@ impl MailConfig {
    pub fn account(&self, name: &str) -> Option<&MailAccountConfig> {
        self.accounts()
            .iter()
            .filter(|a| a.name == name)
            .next()
            .find(|a| a.name == name)
    }

    pub fn fetchcommand(&self) -> &MailCommand {


@@ 74,8 73,7 @@ impl MailConfig {
    pub fn fetchcommand_for_account(&self, account_name: &str) -> &MailCommand {
        self.accounts()
            .iter()
            .filter(|a| a.name == account_name)
            .next()
            .find(|a| a.name == account_name)
            .and_then(|a| a.fetchcommand.as_ref())
            .unwrap_or_else(|| self.fetchcommand())
    }


@@ 83,8 81,7 @@ impl MailConfig {
    pub fn postfetchcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
        self.accounts()
            .iter()
            .filter(|a| a.name == account_name)
            .next()
            .find(|a| a.name == account_name)
            .and_then(|a| a.postfetchcommand.as_ref())
            .or_else(|| self.postfetchcommand())
    }


@@ 92,8 89,7 @@ impl MailConfig {
    pub fn sendcommand_for_account(&self, account_name: &str) -> &MailCommand {
        self.accounts()
            .iter()
            .filter(|a| a.name == account_name)
            .next()
            .find(|a| a.name == account_name)
            .and_then(|a| a.sendcommand.as_ref())
            .unwrap_or_else(|| self.sendcommand())
    }


@@ 101,8 97,7 @@ impl MailConfig {
    pub fn postsendcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
        self.accounts()
            .iter()
            .filter(|a| a.name == account_name)
            .next()
            .find(|a| a.name == account_name)
            .and_then(|a| a.postsendcommand.as_ref())
            .or_else(|| self.postsendcommand())
    }

M lib/domain/libimagmail/src/store.rs => lib/domain/libimagmail/src/store.rs +2 -2
@@ 70,7 70,7 @@ impl<'a> MailStore<'a> for Store {
        let new_sid    = crate::module_path::new_id(message_id.clone())?;

        let mut entry = self.create(new_sid)?;
        let _         = entry
        entry
            .as_ref_with_hasher_mut::<MailHasher>()
            .make_ref(p, collection_name, config, false)?;



@@ 122,7 122,7 @@ impl<'a> MailStore<'a> for Store {
            .get_header_mut()
            .insert("mail.message-id", Value::String(message_id))?;

        let _ = entry
        entry
            .as_ref_with_hasher_mut::<DefaultHasher>()
            .make_ref(p, collection_name, config, false)?;


M lib/domain/libimagtimetrack/src/constants.rs => lib/domain/libimagtimetrack/src/constants.rs +5 -5
@@ 17,9 17,9 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

pub const CRATE_NAME : &'static str                  = "timetrack";
pub const DATE_TIME_FORMAT : &'static str            = "%Y-%m-%dT%H:%M:%S";
pub const DATE_TIME_START_HEADER_PATH : &'static str = "timetrack.start";
pub const DATE_TIME_END_HEADER_PATH : &'static str   = "timetrack.end";
pub const DATE_TIME_TAG_HEADER_PATH : &'static str   = "timetrack.tag";
pub const CRATE_NAME : &str                  = "timetrack";
pub const DATE_TIME_FORMAT : &str            = "%Y-%m-%dT%H:%M:%S";
pub const DATE_TIME_START_HEADER_PATH : &str = "timetrack.start";
pub const DATE_TIME_END_HEADER_PATH : &str   = "timetrack.end";
pub const DATE_TIME_TAG_HEADER_PATH : &str   = "timetrack.tag";


M lib/domain/libimagtimetrack/src/iter/create.rs => lib/domain/libimagtimetrack/src/iter/create.rs +2 -2
@@ 40,8 40,8 @@ impl<'a> CreateTimeTrackIter<'a>
{
    pub fn new(inner: TagStoreIdIter, store: &'a Store) -> CreateTimeTrackIter<'a> {
        CreateTimeTrackIter {
            inner: inner,
            store: store,
            inner,
            store,
        }
    }


M lib/domain/libimagtimetrack/src/iter/filter.rs => lib/domain/libimagtimetrack/src/iter/filter.rs +3 -3
@@ 49,7 49,7 @@ pub fn has_end_time_where<F>(f: F) -> HasEndTimeWhere<F>
    HasEndTimeWhere::new(f)
}

pub fn has_one_of_tags<'a>(tags: &'a Vec<TTT>) -> HasOneOfTags<'a> {
pub fn has_one_of_tags(tags: &[TTT]) -> HasOneOfTags<'_> {
    HasOneOfTags::new(tags)
}



@@ 100,10 100,10 @@ mod types {
        }
    }

    pub struct HasOneOfTags<'a>(&'a Vec<TTT>);
    pub struct HasOneOfTags<'a>(&'a [TTT]);

    impl<'a> HasOneOfTags<'a> {
        pub fn new(tags: &'a Vec<TTT>) -> HasOneOfTags<'a> {
        pub fn new(tags: &'a [TTT]) -> HasOneOfTags<'a> {
            HasOneOfTags(tags)
        }
    }

M lib/domain/libimagtimetrack/src/iter/storeid.rs => lib/domain/libimagtimetrack/src/iter/storeid.rs +2 -2
@@ 39,7 39,7 @@ impl TagStoreIdIter {
        TagStoreIdIter { inner, datetime }
    }

    pub fn create_entries<'a>(self, store: &'a Store) -> CreateTimeTrackIter<'a> {
    pub fn create_entries(self, store: &Store) -> CreateTimeTrackIter<'_> {
        CreateTimeTrackIter::new(self, store)
    }



@@ 56,7 56,7 @@ impl Iterator for TagStoreIdIter {
                let id_str = format!("{}-{}", dt, tag.as_str());
                crate::module_path::new_id(id_str)
                    .map_err(Error::from)
                    .map(|id| (id, self.datetime.clone()))
                    .map(|id| (id, self.datetime))
            }))
    }
}

M lib/domain/libimagtimetrack/src/iter/tag.rs => lib/domain/libimagtimetrack/src/iter/tag.rs +2 -2
@@ 19,7 19,7 @@

use chrono::naive::NaiveDateTime as NDT;
use failure::Fallible as Result;
use failure::Error;

use failure::err_msg;

use crate::tag::TimeTrackingTag as TTT;


@@ 48,7 48,7 @@ impl Iterator for TagIter {
            .map(|t| if is_tag_str(&t).is_ok() {
                Ok(TTT::from(t))
            } else {
                Err(Error::from(err_msg("Error in Tag format")))
                Err(err_msg("Error in Tag format"))
            })
    }
}

M lib/domain/libimagtodo/src/taskstore.rs => lib/domain/libimagtodo/src/taskstore.rs +4 -4
@@ 59,7 59,7 @@ impl<'a> TaskStore<'a> for Store {
            .context(err_msg("Error importing"))
            .map_err(Error::from)
            .and_then(|t| {
                let uuid = t.uuid().clone();
                let uuid = *t.uuid();
                self.new_from_twtask(t).map(|t| (t, line, uuid))
            })
    }


@@ 87,7 87,7 @@ impl<'a> TaskStore<'a> for Store {
        import_task(s.as_str())
            .context(err_msg("Import error"))
            .map_err(Error::from)
            .map(|t| t.uuid().clone())
            .map(|t| *t.uuid())
            .and_then(|uuid| self.get_task_from_uuid(uuid))
            .and_then(|o| match o {
                None    => Ok(Err(s)),


@@ 141,7 141,7 @@ impl<'a> TaskStore<'a> for Store {
                // Here we check if the status of a task is deleted and if yes, we delete it
                // from the store.
                if *ttask.status() == TaskStatus::Deleted {
                    let _ = self.delete_task_by_uuid(*ttask.uuid())?;
                    self.delete_task_by_uuid(*ttask.uuid())?;
                    info!("Deleted task {}", *ttask.uuid());
                }
            }


@@ 154,7 154,7 @@ impl<'a> TaskStore<'a> for Store {
    }

    fn all_tasks(&self) -> Result<TaskIdIterator> {
        self.entries().map(|i| TaskIdIterator::new(i))
        self.entries().map(TaskIdIterator::new)
    }

    fn new_from_twtask(&'a self, task: TTask) -> Result<FileLockEntry<'a>> {

M lib/domain/libimagwiki/src/store.rs => lib/domain/libimagwiki/src/store.rs +1 -1
@@ 41,7 41,7 @@ impl WikiStore for Store {

    /// get a wiki by its name
    fn get_wiki<'a, 'b>(&'a self, name: &'b str) -> Result<Option<Wiki<'a, 'b>>> {
        if self.exists(wiki_path(name.as_ref())?)? {
        if self.exists(wiki_path(name)?)? {
            debug!("Building Wiki object");
            Ok(Some(Wiki::new(self, name)))
        } else {

M lib/domain/libimagwiki/src/wiki.rs => lib/domain/libimagwiki/src/wiki.rs +1 -1
@@ 61,7 61,7 @@ impl<'a, 'b> Wiki<'a, 'b> {
            .get(sid)
            .context("Cannot get ID from store")
            .map_err(Error::from)?
            .ok_or_else(|| Error::from(err_msg("Missing index")))
            .ok_or_else(|| err_msg("Missing index"))
    }

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

M lib/entry/libimagentryannotation/src/annotateable.rs => lib/entry/libimagentryannotation/src/annotateable.rs +3 -3
@@ 54,10 54,10 @@ impl Annotateable for Entry {
        store.retrieve(crate::module_path::new_id(ann_name.clone())?)
            .and_then(|mut anno| {
                {
                    let _ = anno.set_isflag::<IsAnnotation>()?;
                    anno.set_isflag::<IsAnnotation>()?;
                    let _ = anno
                        .get_header_mut()
                        .insert("annotation.name", Value::String(String::from(ann_name)))?;
                        .insert("annotation.name", Value::String(ann_name))?;
                }
                Ok(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_link(&mut annotation)?;
            self.remove_link(&mut annotation)?;
            Ok(Some(annotation))
        } else {
            // error: annotation does not exist

M lib/entry/libimagentrycategory/src/category.rs => lib/entry/libimagentrycategory/src/category.rs +1 -1
@@ 52,7 52,7 @@ impl Category for Entry {
            .read_string(CATEGORY_REGISTER_NAME_FIELD_PATH)
            .context(format_err!("Failed to read header at '{}'", CATEGORY_REGISTER_NAME_FIELD_PATH))
            .map_err(Error::from)?
            .ok_or_else(|| Error::from(err_msg("Category name missing")))
            .ok_or_else(|| err_msg("Category name missing"))
    }

    fn get_entries<'a>(&self, store: &'a Store) -> Result<CategoryEntryIterator<'a>> {

M lib/entry/libimagentrycategory/src/entry.rs => lib/entry/libimagentrycategory/src/entry.rs +4 -4
@@ 65,10 65,10 @@ impl EntryCategory for Entry {
        trace!("Setting category '{}' checked", s);
        let mut category = register
            .get_category_by_name(s)?
            .ok_or_else(|| Error::from(err_msg("Category does not exist")))?;
            .ok_or_else(|| err_msg("Category does not exist"))?;

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

        Ok(())
    }


@@ 77,7 77,7 @@ impl EntryCategory for Entry {
        trace!("Getting category from '{}'", self.get_location());
        self.get_header()
            .read_string("category.value")?
            .ok_or_else(|| Error::from(err_msg("Category name missing")))
            .ok_or_else(|| err_msg("Category name missing"))
    }

    fn has_category(&self) -> Result<bool> {

M lib/entry/libimagentrycategory/src/iter.rs => lib/entry/libimagentrycategory/src/iter.rs +1 -1
@@ 103,7 103,7 @@ impl<'a> Iterator for CategoryEntryIterator<'a> {
                    let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
                        let entry = self.0
                            .get(next)?
                            .ok_or_else(|| Error::from(err_msg("Store read error")))?;
                            .ok_or_else(|| err_msg("Store read error"))?;
                        Ok((entry.get_category()?, entry))
                    };


M lib/entry/libimagentrycategory/src/store.rs => lib/entry/libimagentrycategory/src/store.rs +4 -4
@@ 34,7 34,7 @@ use failure::err_msg;
use crate::iter::CategoryNameIter;
use crate::category::IsCategory;

pub const CATEGORY_REGISTER_NAME_FIELD_PATH : &'static str = "category.register.name";
pub const CATEGORY_REGISTER_NAME_FIELD_PATH : &str = "category.register.name";

/// Extension on the Store to make it a register for categories
///


@@ 92,12 92,12 @@ impl CategoryStore for Store {

        {
            let mut category = self.get(sid.clone())?
                .ok_or_else(|| Error::from(err_msg("Category does not exist")))
                .ok_or_else(|| err_msg("Category does not exist"))
                .map_err(Error::from)?;

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



@@ 201,7 201,7 @@ mod tests {

        match header_field {
            Some(ref s) => assert_eq!(category_name, s),
            None        => assert!(false, "Header field not present"),
            None        => panic!("Header field not present"),
        }
    }
}

M lib/entry/libimagentrydatetime/src/datepath/compiler.rs => lib/entry/libimagentrydatetime/src/datepath/compiler.rs +2 -2
@@ 38,8 38,8 @@ impl DatePathCompiler {

    pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
        DatePathCompiler {
            accuracy : accuracy,
            format   : format,
            accuracy,
            format,
        }
    }


M lib/entry/libimagentrydatetime/src/datetime.rs => lib/entry/libimagentrydatetime/src/datetime.rs +9 -6
@@ 44,10 44,10 @@ pub trait EntryDate {

}

const DATE_HEADER_LOCATION : &'static str              = "datetime.value";
const DATE_RANGE_START_HEADER_LOCATION : &'static str  = "datetime.range.start";
const DATE_RANGE_END_HEADER_LOCATION : &'static str    = "datetime.range.end";
const DATE_FMT : &'static str                          = "%Y-%m-%dT%H:%M:%S";
const DATE_HEADER_LOCATION : &str              = "datetime.value";
const DATE_RANGE_START_HEADER_LOCATION : &str  = "datetime.range.start";
const DATE_RANGE_END_HEADER_LOCATION : &str    = "datetime.range.end";
const DATE_FMT : &str                          = "%Y-%m-%dT%H:%M:%S";

impl EntryDate for Entry {



@@ 114,7 114,7 @@ impl EntryDate for Entry {
    /// header in an inconsistent state.
    ///
    fn delete_date_range(&mut self) -> Result<()> {
        let _ = self
        self
             .get_header_mut()
            .delete(&DATE_RANGE_START_HEADER_LOCATION)
            .map(|_| ())


@@ 228,6 228,7 @@ mod tests {
    fn test_set_date() {
        let store = get_store();

        #[allow(clippy::zero_prefixed_literal)]
        let date = {
            let date = NaiveDate::from_ymd(2000, 01, 02);
            let time = NaiveTime::from_hms(03, 04, 05);


@@ 255,11 256,12 @@ mod tests {

        match *hdr_field {
            Value::String(ref s) => assert_eq!("2000-01-02T03:04:05", s),
            _ => assert!(false, "Wrong header type"),
            _ => panic!("Wrong header type"),
        }
    }

    #[test]
    #[allow(clippy::zero_prefixed_literal)]
    fn test_read_date() {
        use chrono::Datelike;
        use chrono::Timelike;


@@ 300,6 302,7 @@ mod tests {
    fn test_delete_date() {
        let store = get_store();

        #[allow(clippy::zero_prefixed_literal)]
        let date = {
            let date = NaiveDate::from_ymd(2000, 01, 02);
            let time = NaiveTime::from_hms(03, 04, 05);

M lib/entry/libimagentrydatetime/src/range.rs => lib/entry/libimagentrydatetime/src/range.rs +4 -0
@@ 56,11 56,13 @@ mod tests {

    #[test]
    fn test_new_returns_error_if_start_after_end_date() {
        #[allow(clippy::zero_prefixed_literal)]
        let start = NaiveDateTime::new(
            NaiveDate::from_ymd(2000, 02, 02),
            NaiveTime::from_hms(12, 00, 02)
        );

        #[allow(clippy::zero_prefixed_literal)]
        let end = NaiveDateTime::new(
            NaiveDate::from_ymd(2000, 02, 02),
            NaiveTime::from_hms(12, 00, 01)


@@ 73,11 75,13 @@ mod tests {

    #[test]
    fn test_new_returns_ok_if_start_is_before_end() {
        #[allow(clippy::zero_prefixed_literal)]
        let start = NaiveDateTime::new(
            NaiveDate::from_ymd(2000, 02, 02),
            NaiveTime::from_hms(12, 00, 01)
        );

        #[allow(clippy::zero_prefixed_literal)]
        let end = NaiveDateTime::new(
            NaiveDate::from_ymd(2000, 02, 02),
            NaiveTime::from_hms(12, 00, 02)

M lib/entry/libimagentryedit/src/edit.rs => lib/entry/libimagentryedit/src/edit.rs +3 -3
@@ 57,7 57,7 @@ impl EditHeader for Entry {

    fn edit_header(&mut self, rt: &Runtime) -> Result<()> {
        let mut header = ::toml::ser::to_string_pretty(self.get_header())?;
        let _          = edit_in_tmpfile(rt, &mut header)?;
        edit_in_tmpfile(rt, &mut header)?;
        let header     = ::toml::de::from_str(&header)?;
        *self.get_header_mut() = header;
        Ok(())


@@ 65,7 65,7 @@ impl EditHeader for Entry {

    fn edit_header_and_content(&mut self, rt: &Runtime) -> Result<()> {
        let mut header_and_content = self.to_str()?;
        let _                      = edit_in_tmpfile(rt, &mut header_and_content)?;
        edit_in_tmpfile(rt, &mut header_and_content)?;
        self.replace_from_buffer(&header_and_content)
            .context("Failed to replace header and content from buffer")
            .map_err(Error::from)


@@ 79,7 79,7 @@ pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> {
    let editor = rt
        .editor()
        .context(err_msg("No editor"))?
        .ok_or_else(|| Error::from(err_msg("No editor")))?;
        .ok_or_else(|| err_msg("No editor"))?;

    edit_in_tmpfile_with_command(editor, s)
        .context(EM::IO)

M lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs => lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs +7 -7
@@ 51,13 51,13 @@ impl FailableFilter<Entry> for FieldIsEmpty {
             .read(&self.header_field_path[..])?
             .map(|v| {
                 match v {
                     &Value::Array(ref a)   => a.is_empty(),
                     &Value::String(ref s)  => s.is_empty(),
                     &Value::Table(ref t)   => t.is_empty(),
                     &Value::Boolean(_)  |
                     &Value::Float(_)    |
                     &Value::Datetime(_) |
                     &Value::Integer(_)  => false,
                     Value::Array(ref a)   => a.is_empty(),
                     Value::String(ref s)  => s.is_empty(),
                     Value::Table(ref t)   => t.is_empty(),
                     Value::Boolean(_)  |
                     Value::Float(_)    |
                     Value::Datetime(_) |
                     Value::Integer(_)  => false,
                 }
             })
             .unwrap_or(true))

M lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs => lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs +1 -1
@@ 47,7