summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-11-09 22:11:39 +0100
committerMatthias Beyer <mail@beyermatthias.de>2018-11-09 22:11:39 +0100
commit47707bf59331edaef51b43bee54ecb95162f4cc2 (patch)
tree15401404ff5902c7118eaa1cd0a0f071760b09d0
parentecf4cead93da0b04cb74370082dbfc998d7a2752 (diff)
parented08e2ccf98999b106305bd3ac8013d4ef78e17b (diff)
Merge branch 'minor'
-rw-r--r--CODE_OF_CONDUCT.md165
-rw-r--r--README.md7
-rw-r--r--bin/domain/imag-bookmark/src/main.rs15
-rw-r--r--bin/domain/imag-contact/src/main.rs16
-rw-r--r--bin/domain/imag-diary/src/create.rs17
-rw-r--r--bin/domain/imag-habit/src/main.rs51
-rw-r--r--bin/domain/imag-log/src/main.rs113
-rw-r--r--doc/src/09010-contributing.md3
-rw-r--r--lib/domain/libimagtimetrack/src/iter/setendtime.rs20
-rw-r--r--lib/domain/libimagtimetrack/src/iter/storeid.rs23
-rw-r--r--lib/etc/libimagutil/src/debug_option.rs28
-rw-r--r--lib/etc/libimagutil/src/info_option.rs28
-rw-r--r--lib/etc/libimagutil/src/lib.rs3
-rw-r--r--lib/etc/libimagutil/src/log_option.rs88
14 files changed, 270 insertions, 307 deletions
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 3b1709d..0000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,165 +0,0 @@
-# imag Community Code of Conduct
-
-This document was adapted from the KDE code of conduct.
-
-
-## Preamble
-
-This document offers some guidance to ensure imag participants and contributors
-can cooperate
-effectively in a positive and inspiring atmosphere, and to explain how together
-we can strengthen and support each other.
-
-This Code of Conduct is shared by all contributors and users who engage with the
-imag team and its community services.
-
-
-## Overview
-
-This Code of Conduct presents a summary of the shared values and “common sense”
-thinking in our community. The basic social ingredients that hold our project
-together include:
-
- Be considerate
- Be respectful
- Be collaborative
- Be pragmatic
- Support others in the community
- Get support from others in the community
-
-Our community is made up of several groups of individuals and organizations
-which can roughly be divided into two groups:
-
- Contributors, or those who add value to the project through improving imag
- software and its services
- Users, or those who add value to the project through their support as
- consumers of imag software
-
-This Code of Conduct reflects the agreed standards of behavior for members of
-the imag community, in any forum, mailing list, wiki, web site, IRC channel,
-public meeting or private correspondence within the context of the imag team and
-its services. The community acts according to the standards written down in this
-Code of Conduct and will defend these standards for the benefit of the
-community. Leaders of any group, such as moderators of mailing lists, IRC
-channels, forums, etc., will exercise the right to suspend access to any person
-who persistently breaks our shared Code of Conduct.
-
-
-## Be considerate
-
-Your actions and work will affect and be used by other people and you in turn
-will depend on the work and actions of others. Any decision you take will affect
-other community members, and we expect you to take those consequences into
-account when making decisions.
-
-As a contributor, ensure that you give full credit for the work of others and
-bear in mind how your changes affect others. It is also expected that you try to
-follow the development schedule and guidelines.
-
-As a user, remember that contributors work hard on their part of imag and take
-great pride in it. If you are frustrated your problems are more likely to be
-resolved if you can give accurate and well-mannered information to all
-concerned.
-
-
-## Be respectful
-
-In order for the imag community to stay healthy its members must feel
-comfortable and accepted. Treating one another with respect is absolutely
-necessary for this. In a disagreement, in the first instance assume that people
-mean well.
-
-We do not tolerate personal attacks, racism, sexism or any other form of
-discrimination. Disagreement is inevitable, from time to time, but respect for
-the views of others will go a long way to winning respect for your own view.
-Respecting other people, their work, their contributions and assuming
-well-meaning motivation will make community members feel comfortable and safe
-and will result in motivation and productivity.
-
-We expect members of our community to be respectful when dealing with other
-contributors, users and communities. Remember that imag is an international
-project and that you may be unaware of important aspects of other cultures.
-
-
-## Be collaborative
-
-The Free Software Movement depends on collaboration: it helps limit duplication
-of effort while improving the quality of the software produced. In order to
-avoid misunderstanding, try to be clear and concise when requesting help or
-giving it. Remember it is easy to misunderstand emails (especially when they are
-not written in your mother tongue). Ask for clarifications if unsure how
-something is meant; remember the first rule — assume in the first instance that
-people mean well.
-
-As a contributor, you should aim to collaborate with other community members, as
-well as with other communities that are interested in or depend on the work you
-do. Your work should be transparent and be fed back into the community when
-available, not just when imag releases. If you wish to work on something new
-in existing projects, keep those projects informed of your ideas and progress.
-
-It may not always be possible to reach consensus on the implementation of an
-idea, so don't feel obliged to achieve this before you begin. However, always
-ensure that you keep the outside world informed of your work, and publish it in
-a way that allows outsiders to test, discuss and contribute to your efforts.
-
-Contributors on every project come and go. When you leave or disengage from the
-project, in whole or in part, you should do so with pride about what you have
-achieved and by acting responsibly towards others who come after you to continue
-the project.
-
-As a user, your feedback is important, as is its form. Poorly thought out
-comments can cause pain and the demotivation of other community members, but
-considerate discussion of problems can bring positive results. An encouraging
-word works wonders.
-
-
-## Be pragmatic
-
-imag is a pragmatic community. We value tangible results over having the last
-word in a discussion. We defend our core values like freedom and respectful
-collaboration, but we don't let arguments about minor issues get in the way of
-achieving more important results. We are open to suggestions and welcome
-solutions regardless of their origin. When in doubt support a solution which
-helps getting things done over one which has theoretical merits, but isn't being
-worked on. Use the tools and methods which help getting the job done. Let
-decisions be taken by those who do the work.
-
-
-## Support others in the community
-
-Our community is made strong by mutual respect, collaboration and pragmatic,
-responsible behavior. Sometimes there are situations where this has to be
-defended and other community members need help.
-
-If you witness others being attacked, think first about how you can offer them
-personal support. If you feel that the situation is beyond your ability to help
-individually, go privately to the victim and ask if some form of official
-intervention is needed. Similarly you should support anyone who appears to be in
-danger of burning out, either through work-related stress or personal problems.
-
-When problems do arise, consider respectfully reminding those involved of our
-shared Code of Conduct as a first action. Leaders are defined by their actions,
-and can help set a good example by working to resolve issues in the spirit of
-this Code of Conduct before they escalate.
-
-
-## Get support from others in the community
-
-Disagreements, both political and technical, happen all the time. Our community
-is no exception to the rule. The goal is not to avoid disagreements or differing
-views but to resolve them constructively. You should turn to the community to
-seek advice and to resolve disagreements and where possible consult the team
-most directly involved.
-
-Think deeply before turning a disagreement into a public dispute. If necessary
-request mediation, trying to resolve differences in a less highly-emotional
-medium. If you do feel that you or your work is being attacked, take your time
-to breathe through before writing heated replies. Consider a 24-hour moratorium
-if emotional language is being used — a cooling off period is sometimes all that
-is needed. If you really want to go a different way, then we encourage you
-to publish your ideas and your work, so that it can be tried and tested.
-
-
-This document is licensed under the Creative Commons Attribution - Share Alike
-3.0 License.
-
diff --git a/README.md b/README.md
index 05efdba..bf5646e 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ early 2019. I hope I can continue develop imag during that time, but I cannot
guarantee that. I hope I can continue development of imag after that and I
certainly plan to do so.
-But from May 2018 until early 2019, expect long response times.
+But from May 2018 until February 2019, expect long response times.
## Goal / What is imag?
@@ -84,7 +84,7 @@ imag diary -p private create
# Uh, I forgot something in a diary entry, select one (or multiple) and edit it
# use the `fzf` tool here (not a part of imag) to select from the IDs
-imag diary -p private list | fzf -m | imag edit -I
+imag diary -p private list | fzf -m | imag edit
# Link a contact to the diary entry
imag link diary/private/2018/01/01/00:00:00 contact/bc222298-casf-40a4-bda1-50aa980a68c9
@@ -97,8 +97,9 @@ imag notes create "pineapple"
# Where was that contact again?
imag grep Eva # also possible with `imag contact find Eva`
+
# Okay, we need to add some imag-internal notes to that contact
-imag grep Eva -l | imag edit -I
+imag grep Eva -l | imag edit
# Now save our work
imag git add . # "imag-git" simply calls git in the imag store
diff --git a/bin/domain/imag-bookmark/src/main.rs b/bin/domain/imag-bookmark/src/main.rs
index eae6fdf..2d0e22f 100644
--- a/bin/domain/imag-bookmark/src/main.rs
+++ b/bin/domain/imag-bookmark/src/main.rs
@@ -57,6 +57,7 @@ use libimagbookmark::link::Link as BookmarkLink;
use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
+use libimagutil::debug_result::DebugResult;
mod ui;
@@ -152,14 +153,16 @@ fn list(rt: &Runtime) {
.report_touched(collection.get_location())
.map_err_trace_exit_unwrap(1);
- let links = collection.links(rt.store()).map_err_trace_exit_unwrap(1);
- debug!("Listing...");
- for (i, link) in links.enumerate() {
- match link {
+ collection
+ .links(rt.store())
+ .map_dbg_str("Listing...")
+ .map_err_trace_exit_unwrap(1)
+ .into_iter()
+ .enumerate()
+ .for_each(|(i, link)| match link {
Ok(link) => writeln!(rt.stdout(), "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(),
Err(e) => trace_error(&e)
- }
- };
+ });
debug!("... ready with listing");
}
diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs
index dc86208..68f47a4 100644
--- a/bin/domain/imag-contact/src/main.rs
+++ b/bin/domain/imag-contact/src/main.rs
@@ -142,19 +142,15 @@ fn list(rt: &Runtime) {
}
}
} else {
- let rendered = iterator
+ let output = rt.stdout();
+ let mut output = output.lock();
+ iterator
.map(|(i, dvcard)| build_data_object_for_handlebars(i, &dvcard))
.map(|data| list_format.render("format", &data).map_err(Error::from))
.trace_unwrap_exit(1)
- .collect::<Vec<String>>();
- // collect, so that we can have rendered all the things and printing is faster.
-
- let output = rt.stdout();
- let mut output = output.lock();
-
- rendered.into_iter().for_each(|s| {
- writeln!(output, "{}", s).to_exit_code().unwrap_or_exit()
- });
+ .for_each(|s| {
+ writeln!(output, "{}", s).to_exit_code().unwrap_or_exit()
+ });
}
}
diff --git a/bin/domain/imag-diary/src/create.rs b/bin/domain/imag-diary/src/create.rs
index 9d2adb1..2c18339 100644
--- a/bin/domain/imag-diary/src/create.rs
+++ b/bin/domain/imag-diary/src/create.rs
@@ -30,6 +30,8 @@ use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime;
use libimagerror::trace::MapErrTrace;
use libimagutil::warn_exit::warn_exit;
+use libimagutil::debug_result::DebugResult;
+use libimagutil::debug_option::DebugOption;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
@@ -76,7 +78,7 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock
}
})
.map(|timed| {
- let time = create_id_from_clispec(&create, &diaryname, timed);
+ let time = create_id_from_clispec(&create, timed);
diary.new_entry_at(&diaryname, &time)
.context(err_msg("Store write error"))
.map_err(Error::from)
@@ -85,15 +87,12 @@ fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLock
debug!("Creating non-timed entry");
diary.new_entry_today(diaryname)
})
- .map(|e| {
- debug!("Created: {}", e.get_location());
- e
- })
+ .map_dbg(|e| format!("Created: {}", e.get_location()))
.map_err_trace_exit_unwrap(1)
}
-fn create_id_from_clispec(create: &ArgMatches, diaryname: &str, timed_type: Timed) -> NaiveDateTime {
+fn create_id_from_clispec(create: &ArgMatches, timed_type: Timed) -> NaiveDateTime {
use std::str::FromStr;
let dt = Local::now();
@@ -120,7 +119,7 @@ fn create_id_from_clispec(create: &ArgMatches, diaryname: &str, timed_type: Time
Timed::Minutely => {
let min = create
.value_of("minute")
- .map(|m| { debug!("minute = {:?}", m); m })
+ .map_dbg(|m| format!("minute = {:?}", m))
.and_then(|s| {
FromStr::from_str(s)
.map_err(|_| warn!("Could not parse minute: '{}'", s))
@@ -140,7 +139,7 @@ fn create_id_from_clispec(create: &ArgMatches, diaryname: &str, timed_type: Time
Timed::Secondly => {
let min = create
.value_of("minute")
- .map(|m| { debug!("minute = {:?}", m); m })
+ .map_dbg(|m| format!("minute = {:?}", m))
.and_then(|s| {
FromStr::from_str(s)
.map_err(|_| warn!("Could not parse minute: '{}'", s))
@@ -150,7 +149,7 @@ fn create_id_from_clispec(create: &ArgMatches, diaryname: &str, timed_type: Time
let sec = create
.value_of("second")
- .map(|s| { debug!("second = {:?}", s); s })
+ .map_dbg(|s| format!("second = {:?}", s))
.and_then(|s| {
FromStr::from_str(s)
.map_err(|_| warn!("Could not parse second: '{}'", s))
diff --git a/bin/domain/imag-habit/src/main.rs b/bin/domain/imag-habit/src/main.rs
index 8c2c951..36d6ce1 100644
--- a/bin/domain/imag-habit/src/main.rs
+++ b/bin/domain/imag-habit/src/main.rs
@@ -315,7 +315,7 @@ fn today(rt: &Runtime, future: bool) {
info!("No Habits due today.");
info!("Upcoming:");
// list `n` which are relevant in the future.
- for element in relevant.iter().take(n) {
+ relevant.iter().take(n).for_each(|element| {
let date = element.next_instance_date().map_err_trace_exit_unwrap(1);
let name = element.habit_name().map_err_trace_exit_unwrap(1);
@@ -328,7 +328,7 @@ fn today(rt: &Runtime, future: bool) {
info!(" * {date}: {name}", date = date, name = name);
}
}
- }
+ });
} else {
fn lister_fn(h: &FileLockEntry) -> Vec<String> {
debug!("Listing: {:?}", h);
@@ -354,34 +354,33 @@ fn today(rt: &Runtime, future: bool) {
table.set_titles(Row::new(header));
let mut empty = true;
- for (i, e) in relevant.into_iter()
- .filter(|habit| {
- show_done || {
- habit
- .next_instance_date()
- .map_err_trace_exit_unwrap(1)
- .map(|date| {
- habit.instance_exists_for_date(&date)
- .map_err_trace_exit_unwrap(1)
- })
- .unwrap_or(false)
- }
+ relevant
+ .into_iter()
+ .filter(|habit| show_done || {
+ habit
+ .next_instance_date()
+ .map_err_trace_exit_unwrap(1)
+ .map(|date| {
+ habit.instance_exists_for_date(&date)
+ .map_err_trace_exit_unwrap(1)
+ })
+ .unwrap_or(false)
})
.enumerate()
- {
- let mut v = vec![format!("{}", i)];
- let mut list = lister_fn(&e);
+ .for_each(|(i, e)| {
+ let mut v = vec![format!("{}", i)];
+ let mut list = lister_fn(&e);
- {
- let _ = rt
- .report_touched(e.get_location())
- .map_err_trace_exit_unwrap(1);
- }
+ {
+ let _ = rt
+ .report_touched(e.get_location())
+ .map_err_trace_exit_unwrap(1);
+ }
- v.append(&mut list);
- table.add_row(v.iter().map(|s| Cell::new(s)).collect());
- empty = false;
- }
+ v.append(&mut list);
+ table.add_row(v.iter().map(|s| Cell::new(s)).collect());
+ empty = false;
+ });
if !empty {
let _ = table.print(&mut rt.stdout()).to_exit_code().unwrap_or_exit();
diff --git a/bin/domain/imag-log/src/main.rs b/bin/domain/imag-log/src/main.rs
index 5b6f01d..0be4003 100644
--- a/bin/domain/imag-log/src/main.rs
+++ b/bin/domain/imag-log/src/main.rs
@@ -140,42 +140,40 @@ fn show(rt: &Runtime) {
}
};
- for iter in iters {
- let _ = iter
- .into_get_iter(rt.store())
- .trace_unwrap_exit(1)
- .filter_map(|opt| {
- if opt.is_none() {
- warn!("Failed to retrieve an entry from an existing store id");
- }
-
- opt
- })
- .filter(|e| e.is_log().map_err_trace_exit_unwrap(1))
- .map(|entry| (entry.diary_id().map_err_trace_exit_unwrap(1), entry))
- .sorted_by_key(|&(ref id, _)| id.clone())
- .into_iter()
- .map(|(id, entry)| {
- debug!("Found entry: {:?}", entry);
- let _ = writeln!(rt.stdout(),
- "{dname: >10} - {y: >4}-{m:0>2}-{d:0>2}T{H:0>2}:{M:0>2} - {text}",
- dname = id.diary_name(),
- y = id.year(),
- m = id.month(),
- d = id.day(),
- H = id.hour(),
- M = id.minute(),
- text = entry.get_content())
- .to_exit_code()?;
-
- let _ = rt
- .report_touched(entry.get_location())
- .map_err_trace_exit_unwrap(1);
- Ok(())
- })
- .collect::<Result<Vec<()>, ExitCode>>()
- .unwrap_or_exit();
- }
+ Itertools::flatten(iters.into_iter())
+ .into_get_iter(rt.store())
+ .trace_unwrap_exit(1)
+ .filter_map(|opt| {
+ if opt.is_none() {
+ warn!("Failed to retrieve an entry from an existing store id");
+ }
+
+ opt
+ })
+ .filter(|e| e.is_log().map_err_trace_exit_unwrap(1))
+ .map(|entry| (entry.diary_id().map_err_trace_exit_unwrap(1), entry))
+ .sorted_by_key(|tpl| tpl.0.clone())
+ .into_iter()
+ .map(|tpl| { debug!("Found entry: {:?}", tpl.1); tpl })
+ .map(|(id, entry)| {
+ let _ = writeln!(rt.stdout(),
+ "{dname: >10} - {y: >4}-{m:0>2}-{d:0>2}T{H:0>2}:{M:0>2} - {text}",
+ dname = id.diary_name(),
+ y = id.year(),
+ m = id.month(),
+ d = id.day(),
+ H = id.hour(),
+ M = id.minute(),
+ text = entry.get_content())
+ .to_exit_code()?;
+
+ let _ = rt
+ .report_touched(entry.get_location())
+ .map_err_trace_exit_unwrap(1);
+ Ok(())
+ })
+ .collect::<Result<Vec<()>, ExitCode>>()
+ .unwrap_or_exit();
}
fn get_diary_name(rt: &Runtime) -> String {
@@ -187,7 +185,14 @@ fn get_diary_name(rt: &Runtime) -> String {
.ok_or_else(|| Error::from(err_msg("Configuration not present, cannot continue")))
.map_err_trace_exit_unwrap(1);
- let logs = cfg
+ let current_log = cfg
+ .read_string("log.default")
+ .map_err(Error::from)
+ .map_err_trace_exit_unwrap(1)
+ .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.default'")))
+ .map_err_trace_exit_unwrap(1);
+
+ if cfg
.read("log.logs")
.map_err(Error::from)
.map_err_trace_exit_unwrap(1)
@@ -195,34 +200,26 @@ fn get_diary_name(rt: &Runtime) -> String {
.map_err_trace_exit_unwrap(1)
.as_array()
.ok_or_else(|| Error::from(err_msg("Configuration 'log.logs' is not an Array")))
- .map_err_trace_exit_unwrap(1);
-
- if !logs.iter().all(|e| is_match!(e, &Value::String(_))) {
- error!("Configuration 'log.logs' is not an Array<String>!");
- ::std::process::exit(1);
- }
-
- let logs = logs
- .into_iter()
+ .map_err_trace_exit_unwrap(1)
+ .iter()
+ .map(|e| if is_match!(e, &Value::String(_)) {
+ error!("Configuration 'log.logs' is not an Array<String>!");
+ ::std::process::exit(1)
+ } else {
+ e
+ })
.map(Value::as_str)
- .map(Option::unwrap)
+ .map(Option::unwrap) // safe by map from above
.map(String::from)
- .collect::<Vec<String>>();
-
- let current_log = cfg
- .read_string("log.default")
- .map_err(Error::from)
- .map_err_trace_exit_unwrap(1)
- .ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.default'")))
- .map_err_trace_exit_unwrap(1);
-
- if !logs.contains(&current_log) {
+ .filter(|log| log == &current_log)
+ .next()
+ .is_none()
+ {
error!("'log.logs' does not contain 'log.default'");
::std::process::exit(1)
} else {
current_log.into()
}
-
}
fn get_log_text(rt: &Runtime) -> String {
diff --git a/doc/src/09010-contributing.md b/doc/src/09010-contributing.md
index b5858d7..1978ccc 100644
--- a/doc/src/09010-contributing.md
+++ b/doc/src/09010-contributing.md
@@ -21,9 +21,6 @@ reject your patch.
Make sure to test-compile your patchset and, if available, run tests.
-## Finding an issue
-
-
## Prerequisites
The prerequisites are simple: `cargo` and `rustc` in current version (stable)
diff --git a/lib/domain/libimagtimetrack/src/iter/setendtime.rs b/lib/domain/libimagtimetrack/src/iter/setendtime.rs
index 3d2e4ca..6004015 100644
--- a/lib/domain/libimagtimetrack/src/iter/setendtime.rs
+++ b/lib/domain/libimagtimetrack/src/iter/setendtime.rs
@@ -32,13 +32,9 @@ pub struct SetEndTimeIter<'a> {
datetime: NDT,
}
-impl<'a> SetEndTimeIter<'a>
-{
+impl<'a> SetEndTimeIter<'a> {
pub fn new(inner: CreateTimeTrackIter<'a>, datetime: NDT) -> SetEndTimeIter<'a> {
- SetEndTimeIter {
- inner: inner,
- datetime: datetime,
- }
+ SetEndTimeIter { inner, datetime }
}
}
@@ -48,13 +44,11 @@ impl<'a> Iterator for SetEndTimeIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
self.inner
.next()
- .map(|res| {
- res.and_then(|mut fle| {
- let v = Value::String(self.datetime.format(DATE_TIME_FORMAT).to_string());
- let _ = fle.get_header_mut().insert(DATE_TIME_END_HEADER_PATH, v)?;
- Ok(fle)
- })
- })
+ .map(|res| res.and_then(|mut fle| {
+ let v = Value::String(self.datetime.format(DATE_TIME_FORMAT).to_string());
+ let _ = fle.get_header_mut().insert(DATE_TIME_END_HEADER_PATH, v)?;
+ Ok(fle)
+ }))
}
}
diff --git a/lib/domain/libimagtimetrack/src/iter/storeid.rs b/lib/domain/libimagtimetrack/src/iter/storeid.rs
index 91656a3..eef42e7 100644
--- a/lib/domain/libimagtimetrack/src/iter/storeid.rs
+++ b/lib/domain/libimagtimetrack/src/iter/storeid.rs
@@ -36,10 +36,7 @@ pub struct TagStoreIdIter {
impl TagStoreIdIter {
pub fn new(inner: TagIter, datetime: NDT) -> TagStoreIdIter {
- TagStoreIdIter {
- inner: inner,
- datetime: datetime,
- }
+ TagStoreIdIter { inner, datetime }
}
pub fn create_entries<'a>(self, store: &'a Store) -> CreateTimeTrackIter<'a> {
@@ -57,16 +54,14 @@ impl Iterator for TagStoreIdIter {
self.inner
.next()
- .map(|res| {
- res.and_then(|tag| {
- let dt = self.datetime.format(DATE_TIME_FORMAT).to_string();
- let id_str = format!("{}-{}", dt, tag.as_str());
- ModuleEntryPath::new(id_str)
- .into_storeid()
- .map_err(Error::from)
- .map(|id| (id, self.datetime.clone()))
- })
- })
+ .map(|res| res.and_then(|tag| {
+ let dt = self.datetime.format(DATE_TIME_FORMAT).to_string();
+ let id_str = format!("{}-{}", dt, tag.as_str());
+ ModuleEntryPath::new(id_str)
+ .into_storeid()
+ .map_err(Error::from)
+ .map(|id| (id, self.datetime.clone()))
+ }))
}
}
diff --git a/lib/etc/libimagutil/src/debug_option.rs b/lib/etc/libimagutil/src/debug_option.rs
new file mode 100644
index 0000000..b8ae47f
--- /dev/null
+++ b/lib/etc/libimagutil/src/debug_option.rs
@@ -0,0 +1,28 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+// Generates a extension for the `Option<T>`, named `DebugOption` which has functionality to
+// print `T` via `debug!()`.
+generate_option_logging_extension!(
+ DebugOption,
+ map_dbg,
+ map_dbg_str,
+ |s| { debug!("{}", s); }
+);
+
diff --git a/lib/etc/libimagutil/src/info_option.rs b/lib/etc/libimagutil/src/info_option.rs
new file mode 100644
index 0000000..03800af
--- /dev/null
+++ b/lib/etc/libimagutil/src/info_option.rs
@@ -0,0 +1,28 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+// Generates a extension for the `Option<T>`, named `DebugOption` which has functionality to
+// print `T` via `info!()`.
+generate_option_logging_extension!(
+ InfoResult,
+ map_info,
+ map_info_str,
+ |s| { info!("{}", s); }
+);
+
diff --git a/lib/etc/libimagutil/src/lib.rs b/lib/etc/libimagutil/src/lib.rs
index d9b3304..19bc795 100644
--- a/lib/etc/libimagutil/src/lib.rs
+++ b/lib/etc/libimagutil/src/lib.rs
@@ -42,11 +42,14 @@ extern crate tempfile;
extern crate chrono;
#[macro_use] mod log_result;
+#[macro_use] mod log_option;
pub mod cli_validators;
pub mod date;
pub mod debug_result;
+pub mod debug_option;
pub mod edit;
pub mod info_result;
+pub mod info_option;
pub mod key_value_split;
pub mod variants;
pub mod warn_exit;
diff --git a/lib/etc/libimagutil/src/log_option.rs b/lib/etc/libimagutil/src/log_option.rs
new file mode 100644
index 0000000..813eeef
--- /dev/null
+++ b/lib/etc/libimagutil/src/log_option.rs
@@ -0,0 +1,88 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015-2018 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+/// This macro is used to generate extensions for the `Option<T>` type which only have
+/// sideeffects.
+///
+/// This macro is then used to generate debug/info/log/warning/etc extensions.
+///
+/// It is exported, so other crates can use it to generate more specific extensions for
+/// `Option<T>` types
+///
+/// # Parameters
+///
+/// The documentation for the parameters of the macro follow.
+///
+/// ## `$name`
+///
+/// name of the trait to generate
+///
+/// ## `$map_name`
+///
+/// Name of the function which is generated to call the closure with.
+///
+/// This function gets `&T` from `Option<T>` and can now build the argument for
+/// `$closure`. So, this function can, for example, `|e| format!("Look here: {:?}", e)`, the
+/// Option gets fed to `$closure`.
+///
+/// ## `$map_str_name`
+///
+/// Name of the function which is generated to call the closure with.
+///
+/// This function gets simply a `&str` which gets fed to the `$closure` later.
+/// So it can be used to `foo().$map_str_name("Something happened")`
+///
+/// ## `$closure`
+///
+/// The closure which should be called when mapping.
+///
+/// This closure can now do things, but the return value of the closure is discarded.
+/// So, this closure can be used for its sideeffects (logging for example) only.
+///
+/// An example would be: `|element| debug!("Element: {:?}", element)`.
+///
+#[macro_export]
+macro_rules! generate_option_logging_extension {
+ {
+ $name: ident,
+ $map_name: ident,
+ $map_str_name: ident,
+ $closure: expr
+ } => {
+ pub trait $name<T> : Sized {
+
+ fn $map_name<F: FnOnce(&T) -> String>(self, f: F) -> Self;
+
+ fn $map_str_name(self, s: &str) -> Self {
+ self.$map_name(|_| format!("{}", s))
+ }
+
+ }
+
+ impl<T> $name<T> for Option<T> {
+
+ fn $map_name<F: FnOnce(&T) -> String>(self, f: F) -> Self {
+ self.map(|x| { $closure(f(&x)); x })
+ }
+
+ }
+
+ }
+}
+