Merge branch 'minor'
This commit is contained in:
commit
47707bf593
14 changed files with 270 additions and 307 deletions
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -142,17 +142,13 @@ 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| {
|
||||
.for_each(|s| {
|
||||
writeln!(output, "{}", s).to_exit_code().unwrap_or_exit()
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,9 +354,9 @@ 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 || {
|
||||
relevant
|
||||
.into_iter()
|
||||
.filter(|habit| show_done || {
|
||||
habit
|
||||
.next_instance_date()
|
||||
.map_err_trace_exit_unwrap(1)
|
||||
|
@ -365,10 +365,9 @@ fn today(rt: &Runtime, future: bool) {
|
|||
.map_err_trace_exit_unwrap(1)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
.for_each(|(i, e)| {
|
||||
let mut v = vec![format!("{}", i)];
|
||||
let mut list = lister_fn(&e);
|
||||
|
||||
|
@ -381,7 +380,7 @@ fn today(rt: &Runtime, future: bool) {
|
|||
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();
|
||||
|
|
|
@ -140,8 +140,7 @@ fn show(rt: &Runtime) {
|
|||
}
|
||||
};
|
||||
|
||||
for iter in iters {
|
||||
let _ = iter
|
||||
Itertools::flatten(iters.into_iter())
|
||||
.into_get_iter(rt.store())
|
||||
.trace_unwrap_exit(1)
|
||||
.filter_map(|opt| {
|
||||
|
@ -153,10 +152,10 @@ fn show(rt: &Runtime) {
|
|||
})
|
||||
.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())
|
||||
.sorted_by_key(|tpl| tpl.0.clone())
|
||||
.into_iter()
|
||||
.map(|tpl| { debug!("Found entry: {:?}", tpl.1); tpl })
|
||||
.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(),
|
||||
|
@ -175,7 +174,6 @@ fn show(rt: &Runtime) {
|
|||
})
|
||||
.collect::<Result<Vec<()>, ExitCode>>()
|
||||
.unwrap_or_exit();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_diary_name(rt: &Runtime) -> String {
|
||||
|
@ -187,28 +185,6 @@ 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
|
||||
.read("log.logs")
|
||||
.map_err(Error::from)
|
||||
.map_err_trace_exit_unwrap(1)
|
||||
.ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.logs'")))
|
||||
.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(Value::as_str)
|
||||
.map(Option::unwrap)
|
||||
.map(String::from)
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let current_log = cfg
|
||||
.read_string("log.default")
|
||||
.map_err(Error::from)
|
||||
|
@ -216,13 +192,34 @@ fn get_diary_name(rt: &Runtime) -> String {
|
|||
.ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.default'")))
|
||||
.map_err_trace_exit_unwrap(1);
|
||||
|
||||
if !logs.contains(¤t_log) {
|
||||
if cfg
|
||||
.read("log.logs")
|
||||
.map_err(Error::from)
|
||||
.map_err_trace_exit_unwrap(1)
|
||||
.ok_or_else(|| Error::from(err_msg("Configuration missing: 'log.logs'")))
|
||||
.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)
|
||||
.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) // safe by map from above
|
||||
.map(String::from)
|
||||
.filter(|log| log == ¤t_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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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| {
|
||||
.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)
|
||||
})
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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| {
|
||||
.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()))
|
||||
})
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
lib/etc/libimagutil/src/debug_option.rs
Normal file
28
lib/etc/libimagutil/src/debug_option.rs
Normal file
|
@ -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); }
|
||||
);
|
||||
|
28
lib/etc/libimagutil/src/info_option.rs
Normal file
28
lib/etc/libimagutil/src/info_option.rs
Normal file
|
@ -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); }
|
||||
);
|
||||
|
|
@ -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;
|
||||
|
|
88
lib/etc/libimagutil/src/log_option.rs
Normal file
88
lib/etc/libimagutil/src/log_option.rs
Normal file
|
@ -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 })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue