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-----
This commit is contained in:
commit
47044d9ffe
126 changed files with 885 additions and 951 deletions
|
@ -77,22 +77,20 @@ fn main() {
|
||||||
"Add annotations to entries",
|
"Add annotations to entries",
|
||||||
ui::build_ui);
|
ui::build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
match name {
|
||||||
.map(|name| {
|
"add" => add(&rt),
|
||||||
match name {
|
"remove" => remove(&rt),
|
||||||
"add" => add(&rt),
|
"list" => list(&rt),
|
||||||
"remove" => remove(&rt),
|
other => {
|
||||||
"list" => list(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(rt: &Runtime) {
|
fn add(rt: &Runtime) {
|
||||||
|
@ -116,7 +114,7 @@ fn add(rt: &Runtime) {
|
||||||
.annotate(rt.store())
|
.annotate(rt.store())
|
||||||
.map_err_trace_exit_unwrap();
|
.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 {
|
for id in ids {
|
||||||
let mut entry = rt.store().get(id.clone())
|
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()))
|
.ok_or_else(|| format_err!("Not found: {}", id.local_display_string()))
|
||||||
.map_err_trace_exit_unwrap();
|
.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") {
|
if !scmd.is_present("dont-print-name") {
|
||||||
|
@ -134,7 +132,7 @@ fn add(rt: &Runtime) {
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap()
|
.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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,7 +158,7 @@ fn remove(rt: &Runtime) {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
ids.into_iter().for_each(|id| {
|
ids.for_each(|id| {
|
||||||
let mut entry = rt.store()
|
let mut entry = rt.store()
|
||||||
.get(id.clone())
|
.get(id.clone())
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
|
@ -178,7 +176,7 @@ fn remove(rt: &Runtime) {
|
||||||
let loc = an.get_location().clone();
|
let loc = an.get_location().clone();
|
||||||
drop(an);
|
drop(an);
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.delete(loc)
|
.delete(loc)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
@ -205,10 +203,9 @@ fn list(rt: &Runtime) {
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
if ids.len() != 0 {
|
if ids.len() != 0 {
|
||||||
let _ = ids
|
ids
|
||||||
.into_iter()
|
|
||||||
.for_each(|id| {
|
.for_each(|id| {
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.get(id.clone())
|
.get(id.clone())
|
||||||
.map_err_trace_exit_unwrap()
|
.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) {
|
fn list_annotation<'a>(rt: &Runtime, i: usize, a: FileLockEntry<'a>, with_text: bool) {
|
||||||
let _ = if with_text {
|
if with_text {
|
||||||
writeln!(rt.stdout(),
|
writeln!(rt.stdout(),
|
||||||
"--- {i: >5} | {id}\n{text}\n\n",
|
"--- {i: >5} | {id}\n{text}\n\n",
|
||||||
i = i,
|
i = i,
|
||||||
|
|
|
@ -102,7 +102,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
subm.values_of("entry")
|
subm.values_of("entry")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -70,25 +70,23 @@ fn main() {
|
||||||
"Add a category to entries and manage categories",
|
"Add a category to entries and manage categories",
|
||||||
ui::build_ui);
|
ui::build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
match name {
|
||||||
.map(|name| {
|
"set" => set(&rt),
|
||||||
match name {
|
"get" => get(&rt),
|
||||||
"set" => set(&rt),
|
"list-category" => list_category(&rt),
|
||||||
"get" => get(&rt),
|
"create-category" => create_category(&rt),
|
||||||
"list-category" => list_category(&rt),
|
"delete-category" => delete_category(&rt),
|
||||||
"create-category" => create_category(&rt),
|
"list-categories" => list_categories(&rt),
|
||||||
"delete-category" => delete_category(&rt),
|
other => {
|
||||||
"list-categories" => list_categories(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set(rt: &Runtime) {
|
fn set(rt: &Runtime) {
|
||||||
|
@ -103,7 +101,7 @@ fn set(rt: &Runtime) {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
|
StoreIdIterator::new(Box::new(sids.map(Ok)))
|
||||||
.into_get_iter(rt.store())
|
.into_get_iter(rt.store())
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.map(|o| o.unwrap_or_else(|| {
|
.map(|o| o.unwrap_or_else(|| {
|
||||||
|
@ -111,7 +109,7 @@ fn set(rt: &Runtime) {
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
}))
|
}))
|
||||||
.for_each(|mut entry| {
|
.for_each(|mut entry| {
|
||||||
let _ = entry
|
entry
|
||||||
.set_category_checked(rt.store(), &name)
|
.set_category_checked(rt.store(), &name)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
})
|
})
|
||||||
|
@ -129,7 +127,7 @@ fn get(rt: &Runtime) {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
|
StoreIdIterator::new(Box::new(sids.map(Ok)))
|
||||||
.into_get_iter(rt.store())
|
.into_get_iter(rt.store())
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.map(|o| o.unwrap_or_else(|| {
|
.map(|o| o.unwrap_or_else(|| {
|
||||||
|
@ -138,7 +136,7 @@ fn get(rt: &Runtime) {
|
||||||
}))
|
}))
|
||||||
.map(|entry| entry.get_category().map_err_trace_exit_unwrap())
|
.map(|entry| entry.get_category().map_err_trace_exit_unwrap())
|
||||||
.for_each(|name| {
|
.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 {
|
if answer {
|
||||||
info!("Deleting category '{}'", name);
|
info!("Deleting category '{}'", name);
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.delete_category(&name)
|
.delete_category(&name)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
|
@ -111,7 +111,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
subm.values_of(field)
|
subm.values_of(field)
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -92,9 +92,9 @@ impl Diagnostic {
|
||||||
Some(_) => "Non-String type in 'imag.version'".to_owned(),
|
Some(_) => "Non-String type in 'imag.version'".to_owned(),
|
||||||
None => "No 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() {
|
header_sections: match entry.get_header() {
|
||||||
&Value::Table(ref map) => map.keys().count(),
|
Value::Table(ref map) => map.keys().count(),
|
||||||
_ => 0
|
_ => 0
|
||||||
},
|
},
|
||||||
bytecount_content: entry.get_content().as_str().len(),
|
bytecount_content: entry.get_content().as_str().len(),
|
||||||
|
@ -147,7 +147,7 @@ fn main() {
|
||||||
.into_get_iter()
|
.into_get_iter()
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
e.map_err_trace_exit_unwrap()
|
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_err_trace_exit_unwrap()
|
||||||
})
|
})
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
|
@ -258,7 +258,7 @@ fn get_config(rt: &Runtime, s: &'static str) -> Option<String> {
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.map(|opt| match opt {
|
.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");
|
error!("Config type wrong: 'rt.progressbar_style' should be a string");
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
|
|
|
@ -73,7 +73,7 @@ fn main() {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
|
StoreIdIterator::new(Box::new(sids.map(Ok)))
|
||||||
.into_get_iter(rt.store())
|
.into_get_iter(rt.store())
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.map(|o| o.unwrap_or_else(|| {
|
.map(|o| o.unwrap_or_else(|| {
|
||||||
|
@ -82,15 +82,15 @@ fn main() {
|
||||||
}))
|
}))
|
||||||
.for_each(|mut entry| {
|
.for_each(|mut entry| {
|
||||||
if edit_header {
|
if edit_header {
|
||||||
let _ = entry
|
entry
|
||||||
.edit_header_and_content(&rt)
|
.edit_header_and_content(&rt)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
} else if edit_header_only {
|
} else if edit_header_only {
|
||||||
let _ = entry
|
entry
|
||||||
.edit_header(&rt)
|
.edit_header(&rt)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
} else {
|
} else {
|
||||||
let _ = entry
|
entry
|
||||||
.edit_content(&rt)
|
.edit_content(&rt)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("entry")
|
matches.values_of("entry")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -116,20 +116,16 @@ fn main() {
|
||||||
debug!("Adding args = {:?}", args);
|
debug!("Adding args = {:?}", args);
|
||||||
command.args(&args);
|
command.args(&args);
|
||||||
|
|
||||||
match rt.cli().subcommand() {
|
if let (external, Some(ext_m)) = rt.cli().subcommand() {
|
||||||
(external, Some(ext_m)) => {
|
command.arg(external);
|
||||||
command.arg(external);
|
let args = ext_m
|
||||||
let args = ext_m
|
.values_of("")
|
||||||
.values_of("")
|
.map(|vs| vs.map(String::from).collect())
|
||||||
.map(|vs| vs.map(String::from).collect())
|
.unwrap_or_else(|| vec![]);
|
||||||
.unwrap_or_else(|| vec![]);
|
|
||||||
|
|
||||||
debug!("Adding subcommand '{}' and args = {:?}", external, args);
|
debug!("Adding subcommand '{}' and args = {:?}", external, args);
|
||||||
command.args(&args);
|
command.args(&args);
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut out = rt.stdout();
|
let mut out = rt.stdout();
|
||||||
|
|
||||||
debug!("Calling: {:?}", command);
|
debug!("Calling: {:?}", command);
|
||||||
|
@ -151,19 +147,19 @@ fn main() {
|
||||||
debug!("Error calling git");
|
debug!("Error calling git");
|
||||||
match e.kind() {
|
match e.kind() {
|
||||||
ErrorKind::NotFound => {
|
ErrorKind::NotFound => {
|
||||||
let _ = writeln!(out, "Cannot find 'git' executable")
|
writeln!(out, "Cannot find 'git' executable")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
},
|
},
|
||||||
ErrorKind::PermissionDenied => {
|
ErrorKind::PermissionDenied => {
|
||||||
let _ = writeln!(out, "No permission to execute: 'git'")
|
writeln!(out, "No permission to execute: 'git'")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let _ = writeln!(out, "Error spawning: {:?}", e)
|
writeln!(out, "Error spawning: {:?}", e)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
|
|
|
@ -48,7 +48,7 @@ use std::io::Write;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use failure::Error;
|
|
||||||
use failure::err_msg;
|
use failure::err_msg;
|
||||||
|
|
||||||
use libimagstore::storeid::StoreId;
|
use libimagstore::storeid::StoreId;
|
||||||
|
@ -69,21 +69,20 @@ fn main() {
|
||||||
"Add GPS coordinates to entries",
|
"Add GPS coordinates to entries",
|
||||||
ui::build_ui);
|
ui::build_ui);
|
||||||
|
|
||||||
rt.cli().subcommand_name()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.map(|name| {
|
match name {
|
||||||
match name {
|
"add" => add(&rt),
|
||||||
"add" => add(&rt),
|
"remove" => remove(&rt),
|
||||||
"remove" => remove(&rt),
|
"get" => get(&rt),
|
||||||
"get" => get(&rt),
|
other => {
|
||||||
other => {
|
debug!("Unknown command");
|
||||||
debug!("Unknown command");
|
let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli())
|
||||||
let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli())
|
.map_err_trace_exit_unwrap()
|
||||||
.map_err_trace_exit_unwrap()
|
.code()
|
||||||
.code()
|
.map(::std::process::exit);
|
||||||
.map(::std::process::exit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rt_get_ids(rt: &Runtime) -> Vec<StoreId> {
|
fn rt_get_ids(rt: &Runtime) -> Vec<StoreId> {
|
||||||
|
@ -100,11 +99,11 @@ fn add(rt: &Runtime) {
|
||||||
let c = {
|
let c = {
|
||||||
let parse = |value: &str| -> (i64, i64, i64) {
|
let parse = |value: &str| -> (i64, i64, i64) {
|
||||||
debug!("Parsing '{}' into degree, minute and second", value);
|
debug!("Parsing '{}' into degree, minute and second", value);
|
||||||
let ary = value.split(".")
|
let ary = value.split('.')
|
||||||
.map(|v| {debug!("Parsing = {}", v); v})
|
.map(|v| {debug!("Parsing = {}", v); v})
|
||||||
.map(FromStr::from_str)
|
.map(FromStr::from_str)
|
||||||
.map(|elem| {
|
.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()
|
.map_err_trace_exit_unwrap()
|
||||||
})
|
})
|
||||||
.collect::<Vec<i64>>();
|
.collect::<Vec<i64>>();
|
||||||
|
@ -146,7 +145,7 @@ fn add(rt: &Runtime) {
|
||||||
.set_coordinates(c.clone())
|
.set_coordinates(c.clone())
|
||||||
.map_err_trace_exit_unwrap();
|
.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
|
.map_err_trace_exit_unwrap(); // The parsing of the deleted values failed
|
||||||
|
|
||||||
if print_removed {
|
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)
|
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();
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
subm.values_of(field)
|
subm.values_of(field)
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -90,14 +90,18 @@ fn main() {
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.into_get_iter()
|
.into_get_iter()
|
||||||
.filter_map(|res| res.map_err_trace_exit_unwrap())
|
.filter_map(|res| res.map_err_trace_exit_unwrap())
|
||||||
.filter(|entry| pattern.is_match(entry.get_content()))
|
.filter_map(|entry| if pattern.is_match(entry.get_content()) {
|
||||||
.map(|entry| show(&rt, &entry, &pattern, &opts, &mut count))
|
show(&rt, &entry, &pattern, &opts, &mut count);
|
||||||
|
Some(())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
if opts.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 {
|
} else if !opts.files_with_matches {
|
||||||
let _ = writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches",
|
writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches",
|
||||||
overall_count,
|
overall_count,
|
||||||
count,
|
count,
|
||||||
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) {
|
fn show(rt: &Runtime, e: &Entry, re: &Regex, opts: &Options, count: &mut usize) {
|
||||||
if opts.files_with_matches {
|
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 {
|
} else if opts.count {
|
||||||
*count += 1;
|
*count += 1;
|
||||||
} else {
|
} 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 capture in re.captures_iter(e.get_content()) {
|
||||||
for mtch in capture.iter() {
|
for mtch in capture.iter() {
|
||||||
if let Some(m) = mtch {
|
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;
|
*count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = rt.report_touched(e.get_location()).unwrap_or_exit();
|
rt.report_touched(e.get_location()).unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn main() {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.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())
|
.into_get_iter(rt.store())
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.filter_map(|x| x);
|
.filter_map(|x| x);
|
||||||
|
|
|
@ -237,7 +237,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("id")
|
matches.values_of("id")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -54,9 +54,9 @@ use libimagerror::exit::ExitUnwrap;
|
||||||
use libimagerror::io::ToExitCode;
|
use libimagerror::io::ToExitCode;
|
||||||
use libimagrt::runtime::Runtime;
|
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
|
# We ignore the imagrc.toml file by default
|
||||||
#
|
#
|
||||||
# That is because we expect the user to put
|
# That is because we expect the user to put
|
||||||
|
@ -87,10 +87,10 @@ fn main() {
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|mut p| { p.push(".imag"); p })
|
.map(|mut p| { p.push(".imag"); p })
|
||||||
.map(|path| if path.exists() {
|
.map(|path| if path.exists() {
|
||||||
let _ = writeln!(out, "Path '{:?}' already exists!", path)
|
writeln!(out, "Path '{:?}' already exists!", path)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
let _ = writeln!(out, "Cannot continue.")
|
writeln!(out, "Cannot continue.")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
|
@ -105,7 +105,7 @@ fn main() {
|
||||||
store_path.push("store");
|
store_path.push("store");
|
||||||
println!("Creating {}", store_path.display());
|
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");
|
.expect("Failed to create directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ fn main() {
|
||||||
config_path
|
config_path
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = OpenOptions::new()
|
OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(config_path)
|
.open(config_path)
|
||||||
|
@ -126,14 +126,14 @@ fn main() {
|
||||||
get_config()
|
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 write complete config to file");
|
||||||
})
|
})
|
||||||
.expect("Failed to open new configuration file");
|
.expect("Failed to open new configuration file");
|
||||||
|
|
||||||
if find_command("git").is_some() && !matches.is_present("nogit") {
|
if find_command("git").is_some() && !matches.is_present("nogit") {
|
||||||
// we initialize a git repository
|
// 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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
|
|
||||||
|
@ -143,12 +143,12 @@ fn main() {
|
||||||
gitignore_path.to_str().map(String::from).expect("Cannot convert path to string")
|
gitignore_path.to_str().map(String::from).expect("Cannot convert path to string")
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = OpenOptions::new()
|
OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(gitignore_path.clone())
|
.open(gitignore_path.clone())
|
||||||
.map(|mut f| {
|
.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 write complete gitignore to file");
|
||||||
})
|
})
|
||||||
.expect("Failed to open new configuration file");
|
.expect("Failed to open new configuration file");
|
||||||
|
@ -164,14 +164,14 @@ fn main() {
|
||||||
.expect("Calling 'git init' failed");
|
.expect("Calling 'git init' failed");
|
||||||
|
|
||||||
if output.status.success() {
|
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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} 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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(output.status.code().unwrap_or(1));
|
::std::process::exit(output.status.code().unwrap_or(1));
|
||||||
|
@ -184,14 +184,14 @@ fn main() {
|
||||||
.output()
|
.output()
|
||||||
.expect("Calling 'git add' failed");
|
.expect("Calling 'git add' failed");
|
||||||
if output.status.success() {
|
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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} 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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(output.status.code().unwrap_or(1));
|
::std::process::exit(output.status.code().unwrap_or(1));
|
||||||
|
@ -204,30 +204,30 @@ fn main() {
|
||||||
.output()
|
.output()
|
||||||
.expect("Calling 'git commit' failed");
|
.expect("Calling 'git commit' failed");
|
||||||
if output.status.success() {
|
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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} 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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
::std::process::exit(output.status.code().unwrap_or(1));
|
::std::process::exit(output.status.code().unwrap_or(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = writeln!(out, "git stuff finished!")
|
writeln!(out, "git stuff finished!")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} else {
|
||||||
let _ = writeln!(out, "No git repository will be initialized")
|
writeln!(out, "No git repository will be initialized")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = writeln!(out, "Ready. Have fun with imag!")
|
writeln!(out, "Ready. Have fun with imag!")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ extern crate libimagutil;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use failure::Error;
|
|
||||||
use failure::err_msg;
|
use failure::err_msg;
|
||||||
|
|
||||||
use libimagentryurl::linker::UrlLinker;
|
use libimagentryurl::linker::UrlLinker;
|
||||||
|
@ -102,7 +102,7 @@ fn main() {
|
||||||
::std::process::exit(exit_code);
|
::std::process::exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = rt.cli()
|
rt.cli()
|
||||||
.subcommand_name()
|
.subcommand_name()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
match name {
|
match name {
|
||||||
|
@ -120,12 +120,13 @@ fn main() {
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
if let (Some(from), Some(to)) = (rt.cli().value_of("from"), rt.cli().values_of("to")) {
|
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 {
|
} else {
|
||||||
warn_exit("No commandline call", 1)
|
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();
|
.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 {
|
for entry in to {
|
||||||
debug!("Handling 'to' entry: {:?}", entry);
|
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);
|
debug!("Linking externally: {:?} -> {:?}", from, entry);
|
||||||
let url = Url::parse(entry).unwrap_or_else(|e| {
|
let url = Url::parse(entry).unwrap_or_else(|e| {
|
||||||
error!("Error parsing URL: {:?}", 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()
|
.map_err_trace_exit_unwrap()
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
let _ = rt.report_all_touched(iter).unwrap_or_exit();
|
rt.report_all_touched(iter).unwrap_or_exit();
|
||||||
} else {
|
} else {
|
||||||
debug!("Linking internally: {:?} -> {:?}", from, entry);
|
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)
|
::std::process::exit(1)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let _ = from_entry
|
from_entry
|
||||||
.add_link(&mut to_entry)
|
.add_link(&mut to_entry)
|
||||||
.map_err_trace_exit_unwrap();
|
.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);
|
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) {
|
fn remove_linking(rt: &Runtime) {
|
||||||
|
@ -221,11 +222,11 @@ fn remove_linking(rt: &Runtime) {
|
||||||
.for_each(|id| match rt.store().get(id.clone()) {
|
.for_each(|id| match rt.store().get(id.clone()) {
|
||||||
Err(e) => trace_error(&e),
|
Err(e) => trace_error(&e),
|
||||||
Ok(Some(mut to_entry)) => {
|
Ok(Some(mut to_entry)) => {
|
||||||
let _ = to_entry
|
to_entry
|
||||||
.remove_link(&mut from)
|
.remove_link(&mut from)
|
||||||
.map_err_trace_exit_unwrap();
|
.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) => {
|
Ok(None) => {
|
||||||
// looks like this is not an entry, but a filesystem URI and therefor an
|
// 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) {
|
fn unlink(rt: &Runtime) {
|
||||||
|
@ -270,7 +271,7 @@ fn unlink(rt: &Runtime) {
|
||||||
.unlink(rt.store())
|
.unlink(rt.store())
|
||||||
.map_err_trace_exit_unwrap();
|
.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 let Some(link) = link {
|
||||||
if list_plain {
|
if list_plain {
|
||||||
let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link)
|
writeln!(rt.stdout(), "{: <3}: {}", i, link)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -323,7 +324,7 @@ fn list_linkings(rt: &Runtime) {
|
||||||
.into_string();
|
.into_string();
|
||||||
|
|
||||||
if list_plain {
|
if list_plain {
|
||||||
let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link)
|
writeln!(rt.stdout(), "{: <3}: {}", i, link)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else {
|
} 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),
|
Ok(None) => warn!("Not found: {}", id),
|
||||||
Err(e) => trace_error(&e),
|
Err(e) => trace_error(&e),
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = rt.report_touched(&id).unwrap_or_exit();
|
rt.report_touched(&id).unwrap_or_exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
if !list_plain {
|
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
|
Value::Array(links
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|s| Value::String(s.to_owned()))
|
.map(|s| Value::String(s.to_owned()))
|
||||||
|
|
|
@ -121,7 +121,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_id_paths(field: &str, subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
subm.values_of(field)
|
subm.values_of(field)
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -50,7 +50,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("entry")
|
matches.values_of("entry")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -118,11 +118,11 @@ fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
for link in linked_entries.iter_mut() {
|
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()
|
.store()
|
||||||
.move_by_id(sourcename.clone(), destname.clone())
|
.move_by_id(sourcename.clone(), destname.clone())
|
||||||
.map_err(|e| { // on error, re-add links
|
.map_err(|e| { // on error, re-add links
|
||||||
|
@ -132,7 +132,7 @@ fn main() {
|
||||||
})
|
})
|
||||||
.map_err_trace_exit_unwrap();
|
.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
|
// re-add links to moved entry
|
||||||
relink(rt.store(), destname, &mut linked_entries);
|
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 {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,24 +69,22 @@ fn main() {
|
||||||
&version,
|
&version,
|
||||||
"Reference files outside of the store",
|
"Reference files outside of the store",
|
||||||
build_ui);
|
build_ui);
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call: {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call: {}", name);
|
"deref" => deref(&rt),
|
||||||
match name {
|
"create" => create(&rt),
|
||||||
"deref" => deref(&rt),
|
"remove" => remove(&rt),
|
||||||
"create" => create(&rt),
|
"list-dead" => list_dead(&rt),
|
||||||
"remove" => remove(&rt),
|
other => {
|
||||||
"list-dead" => list_dead(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
};
|
||||||
},
|
}
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deref(rt: &Runtime) {
|
fn deref(rt: &Runtime) {
|
||||||
|
@ -121,7 +119,7 @@ fn deref(rt: &Runtime) {
|
||||||
.and_then(|s| writeln!(outlock, "{}", s).map_err(Error::from))
|
.and_then(|s| writeln!(outlock, "{}", s).map_err(Error::from))
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let _ = rt.report_touched(&id).unwrap_or_exit();
|
rt.report_touched(&id).unwrap_or_exit();
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
error!("No entry for id '{}' found", id);
|
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)
|
ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
{
|
{
|
||||||
let _ = entry.as_ref_with_hasher_mut::<DefaultHasher>()
|
entry.as_ref_with_hasher_mut::<DefaultHasher>()
|
||||||
.remove_ref()
|
.remove_ref()
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
} else {
|
} else {
|
||||||
|
@ -208,7 +206,7 @@ fn list_dead(rt: &Runtime) {
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
|
rt.report_touched(entry.get_location()).unwrap_or_exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_id_paths(subm: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
subm.values_of("ID")
|
subm.values_of("ID")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub fn create(rt: &Runtime) {
|
||||||
}
|
}
|
||||||
.map_err_trace_exit_unwrap();
|
.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<()> {
|
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());
|
debug!("Got content with len = {}", content.len());
|
||||||
|
|
||||||
let header = matches.subcommand_matches("entry")
|
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()));
|
|entry_matches| build_toml_header(entry_matches, Entry::default_header()));
|
||||||
|
|
||||||
create_with_content_and_header(rt, path, content, header)
|
create_with_content_and_header(rt, path, content, header)
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn delete(rt: &Runtime) {
|
||||||
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
||||||
debug!("Deleting file at {:?}", id);
|
debug!("Deleting file at {:?}", id);
|
||||||
|
|
||||||
let _ = rt.store()
|
rt.store()
|
||||||
.delete(path)
|
.delete(path)
|
||||||
.map_warn_err(|e| format!("Error: {:?}", e))
|
.map_warn_err(|e| format!("Error: {:?}", e))
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
|
@ -34,10 +34,10 @@ pub fn get(rt: &Runtime) {
|
||||||
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
||||||
debug!("path = {:?}", path);
|
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) => {
|
Some(entry) => {
|
||||||
print_entry(rt, scmd, 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"),
|
None => info!("No entry found"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,30 +31,28 @@ use libimagerror::exit::ExitUnwrap;
|
||||||
use libimagutil::debug_result::*;
|
use libimagutil::debug_result::*;
|
||||||
|
|
||||||
pub fn retrieve(rt: &Runtime) {
|
pub fn retrieve(rt: &Runtime) {
|
||||||
rt.cli()
|
if let Some(scmd) = rt.cli().subcommand_matches("retrieve") {
|
||||||
.subcommand_matches("retrieve")
|
// unwrap() is safe as arg is required
|
||||||
.map(|scmd| {
|
let id = scmd.value_of("id").unwrap();
|
||||||
// unwrap() is safe as arg is required
|
let path = PathBuf::from(id);
|
||||||
let id = scmd.value_of("id").unwrap();
|
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
||||||
let path = PathBuf::from(id);
|
debug!("path = {:?}", path);
|
||||||
let path = StoreId::new(path).map_err_trace_exit_unwrap();
|
|
||||||
debug!("path = {:?}", path);
|
|
||||||
|
|
||||||
rt.store()
|
rt.store()
|
||||||
.retrieve(path.clone())
|
.retrieve(path.clone())
|
||||||
.map(|e| print_entry(rt, scmd, e))
|
.map(|e| print_entry(rt, scmd, e))
|
||||||
.map_dbg_str("No entry")
|
.map_dbg_str("No entry")
|
||||||
.map_dbg(|e| format!("{:?}", e))
|
.map_dbg(|e| format!("{:?}", e))
|
||||||
.map_err_trace_exit_unwrap();
|
.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) {
|
pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {
|
||||||
if do_print_raw(scmd) {
|
if do_print_raw(scmd) {
|
||||||
debug!("Printing raw content...");
|
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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
} else if do_filter(scmd) {
|
} else if do_filter(scmd) {
|
||||||
|
@ -73,7 +71,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
} else {
|
} else {
|
||||||
debug!("Printing header as TOML...");
|
debug!("Printing header as TOML...");
|
||||||
let _ = writeln!(rt.stdout(), "{}", e.get_header())
|
writeln!(rt.stdout(), "{}", e.get_header())
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
@ -81,7 +79,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) {
|
||||||
|
|
||||||
if do_print_content(scmd) {
|
if do_print_content(scmd) {
|
||||||
debug!("Printing content...");
|
debug!("Printing content...");
|
||||||
let _ = writeln!(rt.stdout(), "{}", e.get_content())
|
writeln!(rt.stdout(), "{}", e.get_content())
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,16 @@ pub fn update(rt: &Runtime) {
|
||||||
{
|
{
|
||||||
let e = locked_e.deref_mut();
|
let e = locked_e.deref_mut();
|
||||||
|
|
||||||
scmd.value_of("content")
|
if let Some(new_content) = scmd.value_of("content") {
|
||||||
.map(|new_content| {
|
*e.get_content_mut() = String::from(new_content);
|
||||||
*e.get_content_mut() = String::from(new_content);
|
debug!("New content set");
|
||||||
debug!("New content set");
|
}
|
||||||
});
|
|
||||||
|
|
||||||
*e.get_header_mut() = build_toml_header(scmd, e.get_header().clone());
|
*e.get_header_mut() = build_toml_header(scmd, e.get_header().clone());
|
||||||
debug!("New header set");
|
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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use libimagutil::key_value_split::IntoKeyValue;
|
||||||
pub fn build_toml_header(matches: &ArgMatches, mut header: Value) -> Value {
|
pub fn build_toml_header(matches: &ArgMatches, mut header: Value) -> Value {
|
||||||
debug!("Building header from cli spec");
|
debug!("Building header from cli spec");
|
||||||
if let Some(headerspecs) = matches.values_of("header") {
|
if let Some(headerspecs) = matches.values_of("header") {
|
||||||
let kvs = headerspecs.into_iter()
|
let kvs = headerspecs
|
||||||
.filter_map(|hs| {
|
.filter_map(|hs| {
|
||||||
debug!("- Processing: '{}'", hs);
|
debug!("- Processing: '{}'", hs);
|
||||||
let kv = String::from(hs).into_kv();
|
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();
|
let (key, value) = tpl.into();
|
||||||
debug!("Splitting: {:?}", key);
|
debug!("Splitting: {:?}", key);
|
||||||
let mut split = key.split('.');
|
let mut split = key.split('.');
|
||||||
match (split.next(), &mut header) {
|
if let (Some(cur), &mut Value::Table(ref mut hdr)) = (split.next(), &mut header) {
|
||||||
(Some(cur), &mut Value::Table(ref mut hdr)) =>
|
insert_key_into(String::from(cur), &mut split, Cow::Owned(value), hdr);
|
||||||
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>) {
|
map: &mut Map<String, Value>) {
|
||||||
let next = rest_path.next();
|
let next = rest_path.next();
|
||||||
|
|
||||||
if next.is_none() {
|
if let Some(next) = next {
|
||||||
debug!("Inserting into {:?} = {:?}", current, value);
|
|
||||||
map.insert(current, parse_value(value));
|
|
||||||
} else {
|
|
||||||
debug!("Inserting into {:?} ... = {:?}", current, value);
|
debug!("Inserting into {:?} ... = {:?}", current, value);
|
||||||
match map.entry(current) {
|
match map.entry(current) {
|
||||||
Entry::Occupied(ref mut e) => {
|
Entry::Occupied(ref mut e) => {
|
||||||
match *e.get_mut() {
|
match *e.get_mut() {
|
||||||
Value::Table(ref mut t) => {
|
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!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Entry::Vacant(v) => { v.insert(Value::Table( {
|
Entry::Vacant(v) => { v.insert(Value::Table( {
|
||||||
let mut submap = Map::new();
|
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);
|
debug!("Inserting submap = {:?}", submap);
|
||||||
submap }));
|
submap }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
debug!("Inserting into {:?} = {:?}", current, value);
|
||||||
|
map.insert(current, parse_value(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub fn verify(rt: &Runtime) {
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("{: >6} | {: >14} | {:?}", verify, content_len, p.deref());
|
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
|
status
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,8 @@ fn main() {
|
||||||
})
|
})
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
match name {
|
||||||
.map(|name| match name {
|
|
||||||
"list" => for id in ids {
|
"list" => for id in ids {
|
||||||
list(id, &rt)
|
list(id, &rt)
|
||||||
},
|
},
|
||||||
|
@ -118,7 +117,8 @@ fn main() {
|
||||||
.code()
|
.code()
|
||||||
.map(::std::process::exit);
|
.map(::std::process::exit);
|
||||||
},
|
},
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alter(rt: &Runtime, path: StoreId, add: Option<Vec<Tag>>, rem: Option<Vec<Tag>>) {
|
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)) => {
|
Ok(Some(mut e)) => {
|
||||||
debug!("Entry header now = {:?}", e.get_header());
|
debug!("Entry header now = {:?}", e.get_header());
|
||||||
|
|
||||||
add.map(|tags| {
|
if let Some(tags) = add {
|
||||||
debug!("Adding tags = '{:?}'", tags);
|
debug!("Adding tags = '{:?}'", tags);
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
debug!("Adding tag '{:?}'", tag);
|
debug!("Adding tag '{:?}'", tag);
|
||||||
if let Err(e) = e.add_tag(tag) {
|
if let Err(e) = e.add_tag(tag) {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
} else {
|
} else {
|
||||||
debug!("Adding tag worked");
|
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());
|
debug!("Entry header now = {:?}", e.get_header());
|
||||||
|
|
||||||
rem.map(|tags| {
|
if let Some(tags) = rem {
|
||||||
debug!("Removing tags = '{:?}'", tags);
|
debug!("Removing tags = '{:?}'", tags);
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
debug!("Removing tag '{:?}'", tag);
|
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);
|
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());
|
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) {
|
fn list(path: StoreId, rt: &Runtime) {
|
||||||
|
@ -193,7 +193,7 @@ fn list(path: StoreId, rt: &Runtime) {
|
||||||
|
|
||||||
if line_out {
|
if line_out {
|
||||||
for tag in &tags {
|
for tag in &tags {
|
||||||
let _ = writeln!(rt.stdout(), "{}", tag)
|
writeln!(rt.stdout(), "{}", tag)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
@ -201,18 +201,18 @@ fn list(path: StoreId, rt: &Runtime) {
|
||||||
|
|
||||||
if sepp_out {
|
if sepp_out {
|
||||||
let sepp = scmd.value_of("sep").unwrap(); // we checked before
|
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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if comm_out {
|
if comm_out {
|
||||||
let _ = writeln!(rt.stdout(), "{}", tags.join(", "))
|
writeln!(rt.stdout(), "{}", tags.join(", "))
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.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
|
/// 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)
|
.values_of(v)
|
||||||
.unwrap() // enforced by clap
|
.unwrap() // enforced by clap
|
||||||
.into_iter()
|
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
@ -286,7 +285,7 @@ mod tests {
|
||||||
entry.get_header().read(&"tag.values".to_owned()).map_err(Error::from)
|
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())
|
Value::Array(tags.into_iter().map(|s| Value::String(s.to_owned())).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("id")
|
matches.values_of("id")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -112,12 +112,12 @@ fn main() {
|
||||||
let viewer = rt
|
let viewer = rt
|
||||||
.cli()
|
.cli()
|
||||||
.value_of("in")
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let config = rt
|
let config = rt
|
||||||
.config()
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let query = format!("view.viewers.{}", viewer);
|
let query = format!("view.viewers.{}", viewer);
|
||||||
|
@ -134,7 +134,7 @@ fn main() {
|
||||||
let mut handlebars = Handlebars::new();
|
let mut handlebars = Handlebars::new();
|
||||||
handlebars.register_escape_fn(::handlebars::no_escape);
|
handlebars.register_escape_fn(::handlebars::no_escape);
|
||||||
|
|
||||||
let _ = handlebars
|
handlebars
|
||||||
.register_template_string("template", viewer_template)
|
.register_template_string("template", viewer_template)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
@ -156,7 +156,7 @@ fn main() {
|
||||||
let mut elems = call.split_whitespace();
|
let mut elems = call.split_whitespace();
|
||||||
let command_string = elems
|
let command_string = elems
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::from(err_msg("No command")))
|
.ok_or_else(|| err_msg("No command"))
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
let mut cmd = Command::new(command_string);
|
let mut cmd = Command::new(command_string);
|
||||||
|
|
||||||
|
@ -204,9 +204,8 @@ fn main() {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(n, entry)| {
|
.for_each(|(n, entry)| {
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
seperator
|
if let Some(s) = seperator
|
||||||
.as_ref()
|
.as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
|
||||||
.map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
|
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
|
||||||
|
@ -238,9 +237,8 @@ fn main() {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(n, entry)| {
|
.for_each(|(n, entry)| {
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
seperator
|
if let Some(s) = seperator
|
||||||
.as_ref()
|
.as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
|
||||||
.map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
|
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()
|
.path()
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(String::from)
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
(tmpfile, file_path)
|
(tmpfile, file_path)
|
||||||
|
|
|
@ -93,7 +93,6 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("id")
|
matches.values_of("id")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
|
|
|
@ -102,8 +102,7 @@ fn help_text(cmds: Vec<String>) -> String {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|cmd| format!("\t{}\n", cmd))
|
.map(|cmd| format!("\t{}\n", cmd))
|
||||||
.fold(String::new(), |s, c| {
|
.fold(String::new(), |s, c| {
|
||||||
let s = s + c.as_str();
|
s + c.as_str()
|
||||||
s
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,14 +110,14 @@ fn help_text(cmds: Vec<String>) -> String {
|
||||||
fn get_commands(out: &mut Stdout) -> Vec<String> {
|
fn get_commands(out: &mut Stdout) -> Vec<String> {
|
||||||
let mut v = match env::var("PATH") {
|
let mut v = match env::var("PATH") {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = writeln!(out, "PATH error: {:?}", e)
|
writeln!(out, "PATH error: {:?}", e)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(1)
|
exit(1)
|
||||||
},
|
},
|
||||||
|
|
||||||
Ok(path) => path
|
Ok(path) => path
|
||||||
.split(":")
|
.split(':')
|
||||||
.flat_map(|elem| {
|
.flat_map(|elem| {
|
||||||
WalkDir::new(elem)
|
WalkDir::new(elem)
|
||||||
.max_depth(1)
|
.max_depth(1)
|
||||||
|
@ -131,7 +130,7 @@ fn get_commands(out: &mut Stdout) -> Vec<String> {
|
||||||
.filter_map(|path| path
|
.filter_map(|path| path
|
||||||
.file_name()
|
.file_name()
|
||||||
.to_str()
|
.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) {
|
.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);
|
let print_help = app.clone().get_matches().subcommand_name().map(|h| h == "help").unwrap_or(false);
|
||||||
if print_help {
|
if print_help {
|
||||||
let _ = writeln!(out, "{}", long_help)
|
writeln!(out, "{}", long_help)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -220,7 +219,7 @@ fn main() {
|
||||||
|
|
||||||
if matches.is_present("version") {
|
if matches.is_present("version") {
|
||||||
debug!("Showing version");
|
debug!("Showing version");
|
||||||
let _ = writeln!(out, "imag {}", env!("CARGO_PKG_VERSION"))
|
writeln!(out, "imag {}", env!("CARGO_PKG_VERSION"))
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -248,7 +247,7 @@ fn main() {
|
||||||
})
|
})
|
||||||
.fold((), |_, line| {
|
.fold((), |_, line| {
|
||||||
// The amount of newlines may differ depending on the subprocess
|
// The amount of newlines may differ depending on the subprocess
|
||||||
let _ = writeln!(out, "{}", line.trim())
|
writeln!(out, "{}", line.trim())
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
});
|
});
|
||||||
|
@ -259,85 +258,81 @@ fn main() {
|
||||||
let aliases = match fetch_aliases(config.as_ref()) {
|
let aliases = match fetch_aliases(config.as_ref()) {
|
||||||
Ok(aliases) => aliases,
|
Ok(aliases) => aliases,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = writeln!(out, "Error while fetching aliases from configuration file")
|
writeln!(out, "Error while fetching aliases from configuration file")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
debug!("Error = {:?}", e);
|
debug!("Error = {:?}", e);
|
||||||
let _ = writeln!(out, "Aborting")
|
writeln!(out, "Aborting")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Matches any subcommand given
|
// Matches any subcommand given, except calling for example 'imag --versions', as this option
|
||||||
match matches.subcommand() {
|
// does not exit. There's nothing to do in such a case
|
||||||
(subcommand, Some(scmd)) => {
|
if let (subcommand, Some(scmd)) = matches.subcommand() {
|
||||||
// Get all given arguments and further subcommands to pass to
|
// Get all given arguments and further subcommands to pass to
|
||||||
// the imag-<> binary
|
// the imag-<> binary
|
||||||
// Providing no arguments is OK, and is therefore ignored here
|
// Providing no arguments is OK, and is therefore ignored here
|
||||||
let mut subcommand_args : Vec<String> = match scmd.values_of("") {
|
let mut subcommand_args : Vec<String> = match scmd.values_of("") {
|
||||||
Some(values) => values.map(String::from).collect(),
|
Some(values) => values.map(String::from).collect(),
|
||||||
None => Vec::new()
|
None => Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Processing forwarding of commandline arguments");
|
debug!("Processing forwarding of commandline arguments");
|
||||||
forward_commandline_arguments(&matches, &mut subcommand_args);
|
forward_commandline_arguments(&matches, &mut subcommand_args);
|
||||||
|
|
||||||
let subcommand = String::from(subcommand);
|
let subcommand = String::from(subcommand);
|
||||||
let subcommand = aliases.get(&subcommand).cloned().unwrap_or(subcommand);
|
let subcommand = aliases.get(&subcommand).cloned().unwrap_or(subcommand);
|
||||||
|
|
||||||
debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);
|
debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);
|
||||||
|
|
||||||
// Create a Command, and pass it the gathered arguments
|
// Create a Command, and pass it the gathered arguments
|
||||||
match Command::new(format!("imag-{}", subcommand))
|
match Command::new(format!("imag-{}", subcommand))
|
||||||
.stdin(Stdio::inherit())
|
.stdin(Stdio::inherit())
|
||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
.args(&subcommand_args[..])
|
.args(&subcommand_args[..])
|
||||||
.spawn()
|
.spawn()
|
||||||
.and_then(|mut c| c.wait())
|
.and_then(|mut c| c.wait())
|
||||||
{
|
{
|
||||||
Ok(exit_status) => {
|
Ok(exit_status) => {
|
||||||
if !exit_status.success() {
|
if !exit_status.success() {
|
||||||
debug!("imag-{} exited with non-zero exit code: {:?}", subcommand, exit_status);
|
debug!("imag-{} exited with non-zero exit code: {:?}", subcommand, exit_status);
|
||||||
eprintln!("imag-{} exited with non-zero exit code", subcommand);
|
eprintln!("imag-{} exited with non-zero exit code", subcommand);
|
||||||
exit(exit_status.code().unwrap_or(1));
|
exit(exit_status.code().unwrap_or(1));
|
||||||
}
|
}
|
||||||
debug!("Successful exit!");
|
debug!("Successful exit!");
|
||||||
},
|
},
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Error calling the subcommand");
|
debug!("Error calling the subcommand");
|
||||||
match e.kind() {
|
match e.kind() {
|
||||||
ErrorKind::NotFound => {
|
ErrorKind::NotFound => {
|
||||||
let _ = writeln!(out, "No such command: 'imag-{}'", subcommand)
|
writeln!(out, "No such command: 'imag-{}'", subcommand)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
let _ = writeln!(out, "See 'imag --help' for available subcommands")
|
writeln!(out, "See 'imag --help' for available subcommands")
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(1);
|
exit(1);
|
||||||
},
|
},
|
||||||
ErrorKind::PermissionDenied => {
|
ErrorKind::PermissionDenied => {
|
||||||
let _ = writeln!(out, "No permission to execute: 'imag-{}'", subcommand)
|
writeln!(out, "No permission to execute: 'imag-{}'", subcommand)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(1);
|
exit(1);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let _ = writeln!(out, "Error spawning: {:?}", e)
|
writeln!(out, "Error spawning: {:?}", e)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
exit(1);
|
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();
|
let mut alias_mappings = BTreeMap::new();
|
||||||
|
|
||||||
for (k, v) in tbl {
|
for (k, v) in tbl {
|
||||||
match v {
|
match *v {
|
||||||
&Value::String(ref alias) => {
|
Value::String(ref alias) => {
|
||||||
alias_mappings.insert(alias.clone(), k.clone());
|
alias_mappings.insert(alias.clone(), k.clone());
|
||||||
},
|
},
|
||||||
&Value::Array(ref aliases) => {
|
Value::Array(ref aliases) => {
|
||||||
for alias in aliases {
|
for alias in aliases {
|
||||||
match alias {
|
match *alias {
|
||||||
&Value::String(ref s) => {
|
Value::String(ref s) => {
|
||||||
alias_mappings.insert(s.clone(), k.clone());
|
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);
|
flag = flag, val_name = val_name, matches = m, v = v);
|
||||||
|
|
||||||
if m.is_present(val_name) {
|
if m.is_present(val_name) {
|
||||||
let _ = m
|
m
|
||||||
.value_of(val_name)
|
.value_of(val_name)
|
||||||
.map(|val| {
|
.map(|val| {
|
||||||
debug!("Found '{:?}' = {:?}", val_name, val);
|
debug!("Found '{:?}' = {:?}", val_name, val);
|
||||||
|
|
|
@ -76,24 +76,22 @@ fn main() {
|
||||||
"Bookmark collection tool",
|
"Bookmark collection tool",
|
||||||
build_ui);
|
build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call {}", name);
|
"add" => add(&rt),
|
||||||
match name {
|
"collection" => collection(&rt),
|
||||||
"add" => add(&rt),
|
"list" => list(&rt),
|
||||||
"collection" => collection(&rt),
|
"remove" => remove(&rt),
|
||||||
"list" => list(&rt),
|
other => {
|
||||||
"remove" => remove(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(rt: &Runtime) {
|
fn add(rt: &Runtime) {
|
||||||
|
@ -105,13 +103,13 @@ fn add(rt: &Runtime) {
|
||||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||||
.map_err_trace_exit_unwrap();
|
.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
|
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))
|
let new_ids = BookmarkCollection::add_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
|
||||||
.map_err_trace_exit_unwrap();
|
.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");
|
info!("Ready");
|
||||||
|
@ -123,7 +121,7 @@ fn collection(rt: &Runtime) {
|
||||||
if scmd.is_present("add") { // adding a new collection
|
if scmd.is_present("add") { // adding a new collection
|
||||||
let name = scmd.value_of("add").unwrap();
|
let name = scmd.value_of("add").unwrap();
|
||||||
if let Ok(id) = BookmarkCollectionStore::new(rt.store(), &name) {
|
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);
|
info!("Created: {}", name);
|
||||||
} else {
|
} else {
|
||||||
warn!("Creating collection {} failed", name);
|
warn!("Creating collection {} failed", name);
|
||||||
|
@ -135,7 +133,7 @@ fn collection(rt: &Runtime) {
|
||||||
let name = scmd.value_of("remove").unwrap();
|
let name = scmd.value_of("remove").unwrap();
|
||||||
|
|
||||||
{ // remove all links
|
{ // remove all links
|
||||||
let _ = BookmarkCollectionStore::get(rt.store(), &name)
|
BookmarkCollectionStore::get(rt.store(), &name)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.ok_or_else(|| format_err!("Collection does not exist: {}", name))
|
.ok_or_else(|| format_err!("Collection does not exist: {}", name))
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
|
@ -143,7 +141,7 @@ fn collection(rt: &Runtime) {
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(_) = BookmarkCollectionStore::delete(rt.store(), &name) {
|
if BookmarkCollectionStore::delete(rt.store(), &name).is_ok() {
|
||||||
info!("Deleted: {}", name);
|
info!("Deleted: {}", name);
|
||||||
} else {
|
} else {
|
||||||
warn!("Deleting collection {} failed", name);
|
warn!("Deleting collection {} failed", name);
|
||||||
|
@ -160,13 +158,12 @@ fn list(rt: &Runtime) {
|
||||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||||
.map_err_trace_exit_unwrap();
|
.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
|
collection
|
||||||
.get_links(rt.store())
|
.get_links(rt.store())
|
||||||
.map_dbg_str("Listing...")
|
.map_dbg_str("Listing...")
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, link)| match link {
|
.for_each(|(i, link)| match link {
|
||||||
Ok(link) => writeln!(rt.stdout(), "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(),
|
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))
|
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||||
.map_err_trace_exit_unwrap();
|
.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
|
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))
|
let removed_links = BookmarkCollection::remove_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
|
||||||
.map_err_trace_exit_unwrap();
|
.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");
|
info!("Ready");
|
||||||
|
|
|
@ -56,14 +56,14 @@ use libimagerror::trace::trace_error;
|
||||||
use libimagerror::exit::ExitUnwrap;
|
use libimagerror::exit::ExitUnwrap;
|
||||||
use libimagutil::warn_result::WarnResult;
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
use super::TEMPLATE;
|
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]
|
#[test]
|
||||||
fn test_validity_template_toml() {
|
fn test_validity_template_toml() {
|
||||||
|
@ -203,7 +203,7 @@ pub fn create(rt: &Runtime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let vcard_string = write_component(&vcard);
|
let vcard_string = write_component(&vcard);
|
||||||
let _ = dest
|
dest
|
||||||
.write_all(&vcard_string.as_bytes())
|
.write_all(&vcard_string.as_bytes())
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
@ -219,7 +219,7 @@ pub fn create(rt: &Runtime) {
|
||||||
.create_from_path(&location, &ref_config, &collection_name)
|
.create_from_path(&location, &ref_config, &collection_name)
|
||||||
.map_err_trace_exit_unwrap();
|
.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");
|
info!("Created entry in store");
|
||||||
} else {
|
} else {
|
||||||
|
@ -232,6 +232,7 @@ pub fn create(rt: &Runtime) {
|
||||||
info!("Ready");
|
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> {
|
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);
|
let mut vcard = VcardBuilder::new().with_uid(uuid);
|
||||||
|
|
||||||
|
@ -578,7 +579,7 @@ mod test_parsing {
|
||||||
use std::io::empty;
|
use std::io::empty;
|
||||||
|
|
||||||
// TODO
|
// 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]
|
#[test]
|
||||||
fn test_template_names() {
|
fn test_template_names() {
|
||||||
|
|
|
@ -73,14 +73,12 @@ pub fn edit(rt: &Runtime) {
|
||||||
loop {
|
loop {
|
||||||
let res = edit_contact(&rt, &contact, &ref_config, collection_name, force_override);
|
let res = edit_contact(&rt, &contact, &ref_config, collection_name, force_override);
|
||||||
if !retry {
|
if !retry {
|
||||||
let _ = res.map_err_trace_exit_unwrap();
|
res.map_err_trace_exit_unwrap();
|
||||||
} else {
|
} else if ask_continue(&mut input, &mut output) {
|
||||||
if ask_continue(&mut input, &mut output) {
|
continue;
|
||||||
continue;
|
} else {
|
||||||
} else {
|
exit(1)
|
||||||
exit(1)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,26 +95,24 @@ fn main() {
|
||||||
build_ui);
|
build_ui);
|
||||||
|
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call {}", name);
|
"list" => list(&rt),
|
||||||
match name {
|
"import" => import(&rt),
|
||||||
"list" => list(&rt),
|
"show" => show(&rt),
|
||||||
"import" => import(&rt),
|
"edit" => edit(&rt),
|
||||||
"show" => show(&rt),
|
"find" => find(&rt),
|
||||||
"edit" => edit(&rt),
|
"create" => create(&rt),
|
||||||
"find" => find(&rt),
|
other => {
|
||||||
"create" => create(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(rt: &Runtime) {
|
fn list(rt: &Runtime) {
|
||||||
|
@ -128,10 +126,10 @@ fn list(rt: &Runtime) {
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.into_get_iter()
|
.into_get_iter()
|
||||||
.trace_unwrap_exit()
|
.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()
|
.trace_unwrap_exit()
|
||||||
.map(|fle| {
|
.map(|fle| {
|
||||||
let _ = rt.report_touched(fle.get_location()).unwrap_or_exit();
|
rt.report_touched(fle.get_location()).unwrap_or_exit();
|
||||||
fle
|
fle
|
||||||
})
|
})
|
||||||
.map(|e| e.deser())
|
.map(|e| e.deser())
|
||||||
|
@ -191,7 +189,7 @@ fn import(rt: &Runtime) {
|
||||||
.retrieve_from_path(&path, &ref_config, &collection_name, force_override)
|
.retrieve_from_path(&path, &ref_config, &collection_name, force_override)
|
||||||
.map_err_trace_exit_unwrap();
|
.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() {
|
} else if path.is_dir() {
|
||||||
for entry in WalkDir::new(path).min_depth(1).into_iter() {
|
for entry in WalkDir::new(path).min_depth(1).into_iter() {
|
||||||
let entry = entry
|
let entry = entry
|
||||||
|
@ -205,7 +203,7 @@ fn import(rt: &Runtime) {
|
||||||
.retrieve_from_path(&pb, &ref_config, &collection_name, force_override)
|
.retrieve_from_path(&pb, &ref_config, &collection_name, force_override)
|
||||||
.map_err_trace_exit_unwrap();
|
.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>"));
|
info!("Imported: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));
|
||||||
} else {
|
} else {
|
||||||
warn!("Ignoring non-file: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));
|
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)
|
.render("format", &data)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.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));
|
|| card.fullname().iter().any(|a| str_contains_any(a, &grepstring));
|
||||||
|
|
||||||
if take {
|
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
|
// optimization so we don't have to parse again in the next step
|
||||||
Some((entry, card))
|
Some((entry, card))
|
||||||
|
@ -326,7 +324,7 @@ fn find(rt: &Runtime) {
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let _ = writeln!(rt.stdout(), "{}", s)
|
writeln!(rt.stdout(), "{}", s)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
});
|
});
|
||||||
|
@ -342,17 +340,17 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd:
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
rt.config()
|
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()
|
.map_err_trace_exit_unwrap()
|
||||||
.read_string(config_value_path)
|
.read_string(config_value_path)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap()
|
.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()
|
.map_err_trace_exit_unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut hb = Handlebars::new();
|
let mut hb = Handlebars::new();
|
||||||
let _ = hb
|
hb
|
||||||
.register_template_string("format", fmt)
|
.register_template_string("format", fmt)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
|
@ -30,7 +30,7 @@ use libimagrt::runtime::Runtime;
|
||||||
use libimagstore::store::FileLockEntry;
|
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 mut data = BTreeMap::new();
|
||||||
|
|
||||||
let process_list = |list: &Vec<String>| {
|
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");
|
error!("Failed to get entry");
|
||||||
exit(1)
|
exit(1)
|
||||||
}))
|
}))
|
||||||
.filter_map(move |entry| {
|
.filter(move |entry| {
|
||||||
let deser = entry.deser().map_err_trace_exit_unwrap();
|
let deser = entry.deser().map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
if deser.uid()
|
let id_starts_with_hash = deser.uid()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
error!("Could not get StoreId from Store::all_contacts(). This is a BUG!");
|
error!("Could not get StoreId from Store::all_contacts(). This is a BUG!");
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
})
|
})
|
||||||
.unwrap() // exited above
|
.unwrap() // exited above
|
||||||
.starts_with(hash.as_ref())
|
.starts_with(hash.as_ref());
|
||||||
{
|
|
||||||
let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
|
if id_starts_with_hash {
|
||||||
Some(entry)
|
rt.report_touched(entry.get_location()).unwrap_or_exit();
|
||||||
|
true
|
||||||
} else {
|
} else {
|
||||||
None
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn create(rt: &Runtime) {
|
||||||
|
|
||||||
let mut entry = create_entry(rt.store(), &diaryname, rt);
|
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") {
|
let res = if rt.cli().subcommand_matches("create").unwrap().is_present("no-edit") {
|
||||||
debug!("Not editing new diary entry");
|
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)
|
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!");
|
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))
|
.map_err(|_| warn!("Could not parse minute: '{}'", s))
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
.unwrap_or(ndt.minute());
|
.unwrap_or_else(|| ndt.minute());
|
||||||
|
|
||||||
ndt.with_minute(min)
|
ndt.with_minute(min)
|
||||||
.unwrap_or_else(|| {
|
.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))
|
.map_err(|_| warn!("Could not parse minute: '{}'", s))
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
.unwrap_or(ndt.minute());
|
.unwrap_or_else(|| ndt.minute());
|
||||||
|
|
||||||
let sec = create
|
let sec = create
|
||||||
.value_of("second")
|
.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))
|
.map_err(|_| warn!("Could not parse second: '{}'", s))
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
.unwrap_or(ndt.second());
|
.unwrap_or_else(|| ndt.second());
|
||||||
|
|
||||||
ndt.with_minute(min)
|
ndt.with_minute(min)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
|
|
|
@ -67,9 +67,9 @@ pub fn delete(rt: &Runtime) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = rt.report_touched(&to_del_location).unwrap_or_exit();
|
rt.report_touched(&to_del_location).unwrap_or_exit();
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.delete(to_del_location)
|
.delete(to_del_location)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn list(rt: &Runtime) {
|
||||||
.map(IntoStoreId::into_storeid)
|
.map(IntoStoreId::into_storeid)
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.for_each(|id| {
|
.for_each(|id| {
|
||||||
let _ = rt.report_touched(&id).unwrap_or_exit();
|
rt.report_touched(&id).unwrap_or_exit();
|
||||||
|
|
||||||
if !rt.output_is_pipe() {
|
if !rt.output_is_pipe() {
|
||||||
writeln!(rt.stdout(), "{}", id).to_exit_code().unwrap_or_exit()
|
writeln!(rt.stdout(), "{}", id).to_exit_code().unwrap_or_exit()
|
||||||
|
|
|
@ -79,25 +79,23 @@ fn main() {
|
||||||
"Personal Diary/Diaries",
|
"Personal Diary/Diaries",
|
||||||
ui::build_ui);
|
ui::build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call {}", name);
|
"diaries" => diaries(&rt),
|
||||||
match name {
|
"create" => create(&rt),
|
||||||
"diaries" => diaries(&rt),
|
"delete" => delete(&rt),
|
||||||
"create" => create(&rt),
|
"list" => list(&rt),
|
||||||
"delete" => delete(&rt),
|
"view" => view(&rt),
|
||||||
"list" => list(&rt),
|
other => {
|
||||||
"view" => view(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
}
|
||||||
},
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diaries(rt: &Runtime) {
|
fn diaries(rt: &Runtime) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub fn view(rt: &Runtime) {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let entries = entries.map(|e| {
|
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
|
e
|
||||||
});
|
});
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn main() {
|
||||||
ui::build_ui);
|
ui::build_ui);
|
||||||
|
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.cli()
|
.cli()
|
||||||
.subcommand_name()
|
.subcommand_name()
|
||||||
.map(|name| {
|
.map(|name| {
|
||||||
|
@ -155,7 +155,7 @@ fn create(rt: &Runtime) {
|
||||||
debug!("Builder = {:?}", hb);
|
debug!("Builder = {:?}", hb);
|
||||||
|
|
||||||
let fle = hb.build(rt.store()).map_err_trace_exit_unwrap();
|
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) {
|
fn delete(rt: &Runtime) {
|
||||||
|
@ -180,8 +180,8 @@ fn delete(rt: &Runtime) {
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.map(|sid| (sid.clone(), rt.store().get(sid).map_err_trace_exit_unwrap())) // get the FileLockEntry
|
.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
|
.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,
|
Some(ref h) => h.habit_name().map_err_trace_exit_unwrap() == name,
|
||||||
&None => false,
|
None => false,
|
||||||
})
|
})
|
||||||
.filter_map(|(a, o)| o.map(|x| (a, x))) // map: (a, Option<b>) -> Option<(a, b)> -> (a, b)
|
.filter_map(|(a, o)| o.map(|x| (a, x))) // map: (a, Option<b>) -> Option<(a, b)> -> (a, b)
|
||||||
.map(|(sid, fle)| {
|
.map(|(sid, fle)| {
|
||||||
|
@ -201,10 +201,10 @@ fn delete(rt: &Runtime) {
|
||||||
if ask_bool(&q, Some(false), &mut input, &mut output)
|
if ask_bool(&q, Some(false), &mut input, &mut output)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
{
|
{
|
||||||
let _ = do_delete(id);
|
do_delete(id);
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
if ask_bool(&q, Some(false), &mut input, &mut output)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
{
|
{
|
||||||
let _ = do_delete_template(sid);
|
do_delete_template(sid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let _ = do_delete_template(sid);
|
do_delete_template(sid);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -253,12 +253,10 @@ fn today(rt: &Runtime, future: bool) {
|
||||||
let futu = scmd.is_present("today-show-future");
|
let futu = scmd.is_present("today-show-future");
|
||||||
let done = scmd.is_present("today-done");
|
let done = scmd.is_present("today-done");
|
||||||
(futu, done)
|
(futu, done)
|
||||||
|
} else if let Some(status) = rt.cli().subcommand_matches("status") {
|
||||||
|
(true, status.is_present("status-done"))
|
||||||
} else {
|
} else {
|
||||||
if let Some(status) = rt.cli().subcommand_matches("status") {
|
(true, false)
|
||||||
(true, status.is_present("status-done"))
|
|
||||||
} else {
|
|
||||||
(true, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let today = ::chrono::offset::Local::today().naive_local();
|
let today = ::chrono::offset::Local::today().naive_local();
|
||||||
|
@ -329,7 +327,7 @@ fn today(rt: &Runtime, future: bool) {
|
||||||
|
|
||||||
if let Some(date) = date {
|
if let Some(date) = date {
|
||||||
let is_done = element
|
let is_done = element
|
||||||
.instance_exists_for_date(&date)
|
.instance_exists_for_date(date)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
if show_done || !is_done {
|
if show_done || !is_done {
|
||||||
|
@ -370,7 +368,7 @@ fn today(rt: &Runtime, future: bool) {
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.map(|date| {
|
.map(|date| {
|
||||||
let instance_exists = habit
|
let instance_exists = habit
|
||||||
.instance_exists_for_date(&date)
|
.instance_exists_for_date(date)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
debug!("instance exists for {:?} for {:?} = {:?}",
|
debug!("instance exists for {:?} for {:?} = {:?}",
|
||||||
|
@ -390,7 +388,7 @@ fn today(rt: &Runtime, future: bool) {
|
||||||
let mut list = lister_fn(&e);
|
let mut list = lister_fn(&e);
|
||||||
|
|
||||||
{
|
{
|
||||||
let _ = rt
|
rt
|
||||||
.report_touched(e.get_location())
|
.report_touched(e.get_location())
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
}
|
}
|
||||||
|
@ -414,7 +412,7 @@ fn list(rt: &Runtime) {
|
||||||
let recur = h.habit_recur_spec().map_err_trace_exit_unwrap();
|
let recur = h.habit_recur_spec().map_err_trace_exit_unwrap();
|
||||||
let comm = h.habit_comment().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 (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(|b| if b { "x" } else { "" })
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
@ -438,7 +436,7 @@ fn list(rt: &Runtime) {
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.set_titles(Row::new(header));
|
table.set_titles(Row::new(header));
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.all_habit_templates()
|
.all_habit_templates()
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
|
@ -460,7 +458,7 @@ fn list(rt: &Runtime) {
|
||||||
let mut list = lister_fn(&e);
|
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);
|
v.append(&mut list);
|
||||||
|
@ -484,7 +482,7 @@ fn show(rt: &Runtime) {
|
||||||
use libimagutil::date::date_to_string;
|
use libimagutil::date::date_to_string;
|
||||||
use libimaghabit::instance::HabitInstance;
|
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();
|
let comm = i.get_comment(rt.store()).map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
vec![date, comm]
|
vec![date, comm]
|
||||||
|
@ -512,7 +510,7 @@ fn show(rt: &Runtime) {
|
||||||
let recur = habit.habit_recur_spec().map_err_trace_exit_unwrap();
|
let recur = habit.habit_recur_spec().map_err_trace_exit_unwrap();
|
||||||
let comm = habit.habit_comment().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} - {name}\nBase : {b},\nRecurrence: {r}\nComment : {c}\n",
|
||||||
i = i,
|
i = i,
|
||||||
name = name,
|
name = name,
|
||||||
|
@ -544,7 +542,7 @@ fn show(rt: &Runtime) {
|
||||||
let mut instances = instance_lister_fn(&rt, &e);
|
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);
|
v.append(&mut instances);
|
||||||
|
@ -574,7 +572,7 @@ fn done(rt: &Runtime) {
|
||||||
.filter_map(|id| get_from_store(rt.store(), id))
|
.filter_map(|id| get_from_store(rt.store(), id))
|
||||||
.filter(|h| {
|
.filter(|h| {
|
||||||
let due = h.next_instance_date().map_err_trace_exit_unwrap();
|
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)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.filter(|h| {
|
.filter(|h| {
|
||||||
|
@ -592,11 +590,11 @@ fn done(rt: &Runtime) {
|
||||||
let next_instance_date = r.next_instance_date().map_err_trace_exit_unwrap();
|
let next_instance_date = r.next_instance_date().map_err_trace_exit_unwrap();
|
||||||
if let Some(next) = next_instance_date {
|
if let Some(next) = next_instance_date {
|
||||||
debug!("Creating new instance on {:?}", next);
|
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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
info!("Done on {date}: {name}",
|
info!("Done on {date}: {name}",
|
||||||
date = libimagutil::date::date_to_string(&next),
|
date = libimagutil::date::date_to_string(next),
|
||||||
name = next_instance_name);
|
name = next_instance_name);
|
||||||
} else {
|
} else {
|
||||||
info!("Ignoring: {}, because there is no due date (the habit is finised)",
|
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.
|
/// 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()) {
|
match store.get(id.clone()) {
|
||||||
Ok(Some(h)) => Some(h),
|
Ok(Some(h)) => Some(h),
|
||||||
Ok(None) => {
|
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 {
|
fn date_to_string_helper(d: chrono::NaiveDate) -> String {
|
||||||
libimagutil::date::date_to_string(&d)
|
libimagutil::date::date_to_string(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,11 +104,11 @@ fn main() {
|
||||||
|
|
||||||
debug!("Writing to '{}': {}", diary_name, text);
|
debug!("Writing to '{}': {}", diary_name, text);
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.new_entry_now(&diary_name)
|
.new_entry_now(&diary_name)
|
||||||
.map(|mut fle| {
|
.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.get_content_mut() = text;
|
||||||
fle
|
fle
|
||||||
})
|
})
|
||||||
|
@ -177,7 +177,6 @@ fn show(rt: &Runtime) {
|
||||||
.filter(|e| e.is_log().map_err_trace_exit_unwrap())
|
.filter(|e| e.is_log().map_err_trace_exit_unwrap())
|
||||||
.map(|entry| (entry.diary_id().map_err_trace_exit_unwrap(), entry))
|
.map(|entry| (entry.diary_id().map_err_trace_exit_unwrap(), entry))
|
||||||
.sorted_by_key(|tpl| tpl.0.get_date_representation())
|
.sorted_by_key(|tpl| tpl.0.get_date_representation())
|
||||||
.into_iter()
|
|
||||||
.map(|tpl| { debug!("Found entry: {:?}", tpl.1); tpl })
|
.map(|tpl| { debug!("Found entry: {:?}", tpl.1); tpl })
|
||||||
.map(|(id, entry)| {
|
.map(|(id, entry)| {
|
||||||
if let Some(wrap_limit) = do_wrap {
|
if let Some(wrap_limit) = do_wrap {
|
||||||
|
@ -186,20 +185,20 @@ fn show(rt: &Runtime) {
|
||||||
// 10 + 4 + 2 + 2 + 2 + 2 + 6 + 4 = 32
|
// 10 + 4 + 2 + 2 + 2 + 2 + 6 + 4 = 32
|
||||||
// plus text, which we assume to be 120 characters... lets allocate 256 bytes.
|
// plus text, which we assume to be 120 characters... lets allocate 256 bytes.
|
||||||
let mut buffer = Cursor::new(Vec::with_capacity(256));
|
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())
|
let buffer = String::from_utf8(buffer.into_inner())
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
// now lets wrap
|
// now lets wrap
|
||||||
for line in ::textwrap::wrap(&buffer, wrap_limit).iter() {
|
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 {
|
} 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())
|
.report_touched(entry.get_location())
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -214,24 +213,24 @@ fn get_diary_name(rt: &Runtime) -> String {
|
||||||
|
|
||||||
let cfg = rt
|
let cfg = rt
|
||||||
.config()
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
let current_log = cfg
|
let current_log = cfg
|
||||||
.read_string("log.default")
|
.read_string("log.default")
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap()
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
if cfg
|
if cfg
|
||||||
.read("log.logs")
|
.read("log.logs")
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map_err_trace_exit_unwrap()
|
.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()
|
.map_err_trace_exit_unwrap()
|
||||||
.as_array()
|
.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()
|
.map_err_trace_exit_unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| if !is_match!(e, &Value::String(_)) {
|
.map(|e| if !is_match!(e, &Value::String(_)) {
|
||||||
|
@ -243,14 +242,13 @@ fn get_diary_name(rt: &Runtime) -> String {
|
||||||
.map(Value::as_str)
|
.map(Value::as_str)
|
||||||
.map(Option::unwrap) // safe by map from above
|
.map(Option::unwrap) // safe by map from above
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.filter(|log| log == ¤t_log)
|
.find(|log| log == ¤t_log)
|
||||||
.next()
|
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
error!("'log.logs' does not contain 'log.default'");
|
error!("'log.logs' does not contain 'log.default'");
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
} else {
|
} else {
|
||||||
current_log.into()
|
current_log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,23 +80,21 @@ fn main() {
|
||||||
"Mail collection tool",
|
"Mail collection tool",
|
||||||
build_ui);
|
build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call {}", name);
|
"import-mail" => import_mail(&rt),
|
||||||
match name {
|
"list" => list(&rt),
|
||||||
"import-mail" => import_mail(&rt),
|
"mail-store" => mail_store(&rt),
|
||||||
"list" => list(&rt),
|
other => {
|
||||||
"mail-store" => mail_store(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
|
||||||
.map(::std::process::exit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_mail(rt: &Runtime) {
|
fn import_mail(rt: &Runtime) {
|
||||||
|
@ -211,7 +209,7 @@ fn list(rt: &Runtime) {
|
||||||
).to_exit_code().unwrap_or_exit();
|
).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() {
|
if rt.ids_from_stdin() {
|
||||||
|
|
|
@ -83,12 +83,11 @@ impl IdPathProvider for PathProvider {
|
||||||
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
fn get_ids(matches: &ArgMatches) -> Result<Option<Vec<StoreId>>> {
|
||||||
matches.values_of("list-id")
|
matches.values_of("list-id")
|
||||||
.map(|v| v
|
.map(|v| v
|
||||||
.into_iter()
|
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
.map(|pb| pb.into_storeid())
|
.map(|pb| pb.into_storeid())
|
||||||
.collect::<Result<Vec<_>>>()
|
.collect::<Result<Vec<_>>>()
|
||||||
)
|
)
|
||||||
.unwrap_or(Ok(Vec::new()))
|
.unwrap_or_else(|| Ok(Vec::new()))
|
||||||
.map(Some)
|
.map(Some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,24 +74,22 @@ fn main() {
|
||||||
"Note taking helper",
|
"Note taking helper",
|
||||||
build_ui);
|
build_ui);
|
||||||
|
|
||||||
rt.cli()
|
if let Some(name) = rt.cli().subcommand_name() {
|
||||||
.subcommand_name()
|
debug!("Call: {}", name);
|
||||||
.map(|name| {
|
match name {
|
||||||
debug!("Call: {}", name);
|
"create" => create(&rt),
|
||||||
match name {
|
"delete" => delete(&rt),
|
||||||
"create" => create(&rt),
|
"edit" => edit(&rt),
|
||||||
"delete" => delete(&rt),
|
"list" => list(&rt),
|
||||||
"edit" => edit(&rt),
|
other => {
|
||||||
"list" => list(&rt),
|
debug!("Unknown command");
|
||||||
other => {
|
let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli())
|
||||||
debug!("Unknown command");
|
.map_err_trace_exit_unwrap()
|
||||||
let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli())
|
.code()
|
||||||
.map_err_trace_exit_unwrap()
|
.map(::std::process::exit);
|
||||||
.code()
|
},
|
||||||
.map(::std::process::exit);
|
};
|
||||||
},
|
}
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name_from_cli(rt: &Runtime, subcmd: &str) -> String {
|
fn name_from_cli(rt: &Runtime, subcmd: &str) -> String {
|
||||||
|
@ -106,17 +104,17 @@ fn create(rt: &Runtime) {
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
|
||||||
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") {
|
if rt.cli().subcommand_matches("create").unwrap().is_present("edit") {
|
||||||
let _ = note
|
note
|
||||||
.edit_content(rt)
|
.edit_content(rt)
|
||||||
.map_warn_err_str("Editing failed")
|
.map_warn_err_str("Editing failed")
|
||||||
.map_err_trace_exit_unwrap();
|
.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) {
|
fn delete(rt: &Runtime) {
|
||||||
let _ = rt.store()
|
rt.store()
|
||||||
.delete_note(name_from_cli(rt, "delete"))
|
.delete_note(name_from_cli(rt, "delete"))
|
||||||
.map_info_str("Ok")
|
.map_info_str("Ok")
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
|
@ -124,17 +122,17 @@ fn delete(rt: &Runtime) {
|
||||||
|
|
||||||
fn edit(rt: &Runtime) {
|
fn edit(rt: &Runtime) {
|
||||||
let name = name_from_cli(rt, "edit");
|
let name = name_from_cli(rt, "edit");
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.get_note(name.clone())
|
.get_note(name.clone())
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.map(|mut note| {
|
.map(|mut note| {
|
||||||
let _ = note
|
note
|
||||||
.edit_content(rt)
|
.edit_content(rt)
|
||||||
.map_warn_err_str("Editing failed")
|
.map_warn_err_str("Editing failed")
|
||||||
.map_err_trace_exit_unwrap();
|
.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(|| {
|
.unwrap_or_else(|| {
|
||||||
error!("Cannot find note with name '{}'", name);
|
error!("Cannot find note with name '{}'", name);
|
||||||
|
@ -144,7 +142,7 @@ fn edit(rt: &Runtime) {
|
||||||
fn list(rt: &Runtime) {
|
fn list(rt: &Runtime) {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
let _ = rt
|
rt
|
||||||
.store()
|
.store()
|
||||||
.all_notes()
|
.all_notes()
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
|
@ -155,17 +153,17 @@ fn list(rt: &Runtime) {
|
||||||
exit(1)
|
exit(1)
|
||||||
}))
|
}))
|
||||||
.sorted_by(|note_a, note_b| if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
|
.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 {
|
} else {
|
||||||
return Ordering::Greater;
|
Ordering::Greater
|
||||||
})
|
})
|
||||||
.for_each(|note| {
|
.for_each(|note| {
|
||||||
let name = note.get_name().map_err_trace_exit_unwrap();
|
let name = note.get_name().map_err_trace_exit_unwrap();
|
||||||
let _ = writeln!(rt.stdout(), "{}", name)
|
writeln!(rt.stdout(), "{}", name)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
|
|
||||||
let _ = rt.report_touched(note.get_location()).unwrap_or_exit();
|
rt.report_touched(note.get_location()).unwrap_or_exit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ pub fn cont(rt: &Runtime) -> i32 {
|
||||||
let (k2, _) = *t2;
|
let (k2, _) = *t2;
|
||||||
Ord::cmp(&k1, &k2)
|
Ord::cmp(&k1, &k2)
|
||||||
})
|
})
|
||||||
.into_iter()
|
|
||||||
|
|
||||||
// get the last one, which should be the highest one
|
// get the last one, which should be the highest one
|
||||||
.last() // -> Option<_>
|
.last() // -> Option<_>
|
||||||
|
@ -88,7 +87,7 @@ pub fn cont(rt: &Runtime) -> i32 {
|
||||||
.map(|_| 0)
|
.map(|_| 0)
|
||||||
.map_err_trace();
|
.map_err_trace();
|
||||||
|
|
||||||
let _ = rt.report_touched(tracking.get_location()).unwrap_or_exit();
|
rt.report_touched(tracking.get_location()).unwrap_or_exit();
|
||||||
|
|
||||||
val
|
val
|
||||||
})
|
})
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub fn day(rt: &Runtime) -> i32 {
|
||||||
|
|
||||||
let tags = cmd
|
let tags = cmd
|
||||||
.values_of("tags")
|
.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| {
|
let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
|
||||||
start <= *dt
|
start <= *dt
|
||||||
|
@ -78,7 +78,7 @@ pub fn day(rt: &Runtime) -> i32 {
|
||||||
});
|
});
|
||||||
|
|
||||||
let tags_filter = move |fle: &FileLockEntry| {
|
let tags_filter = move |fle: &FileLockEntry| {
|
||||||
match tags {
|
match &tags {
|
||||||
Some(ref tags) => has_one_of_tags(&tags).filter(fle),
|
Some(ref tags) => has_one_of_tags(&tags).filter(fle),
|
||||||
None => true,
|
None => true,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ pub fn day(rt: &Runtime) -> i32 {
|
||||||
let end = e.get_end_datetime()?;
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
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))
|
Ok((tag, start, end))
|
||||||
})
|
})
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub fn list(rt: &Runtime) -> i32 {
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(dt.clone())
|
Some(*dt)
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to calculate date from '{}': {:?}",
|
error!("Failed to calculate date from '{}': {:?}",
|
||||||
|
@ -66,7 +66,7 @@ pub fn list(rt: &Runtime) -> i32 {
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
},
|
},
|
||||||
Some(Err(e)) => {
|
Some(Err(e)) => {
|
||||||
let e = Error::from(e);
|
let e = e;
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
::std::process::exit(1)
|
::std::process::exit(1)
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ pub fn list_impl(rt: &Runtime,
|
||||||
.collect();
|
.collect();
|
||||||
tab.add_row(Row::new(cells));
|
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;
|
table_empty = false;
|
||||||
Ok(tab)
|
Ok(tab)
|
||||||
|
|
|
@ -82,7 +82,7 @@ pub fn month(rt: &Runtime) -> i32 {
|
||||||
|
|
||||||
let tags = cmd
|
let tags = cmd
|
||||||
.values_of("tags")
|
.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| {
|
let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
|
||||||
start <= *dt
|
start <= *dt
|
||||||
|
@ -119,7 +119,7 @@ pub fn month(rt: &Runtime) -> i32 {
|
||||||
let end = e.get_end_datetime()?;
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
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))
|
Ok((tag, start, end))
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub fn shell(rt: &Runtime) -> i32 {
|
||||||
mkshell(s.to_owned())
|
mkshell(s.to_owned())
|
||||||
} else {
|
} else {
|
||||||
env::var("SHELL")
|
env::var("SHELL")
|
||||||
.map(|s| mkshell(s))
|
.map(mkshell)
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
env::VarError::NotPresent => {
|
env::VarError::NotPresent => {
|
||||||
error!("No $SHELL variable in environment, cannot work!");
|
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) {
|
match rt.store().create_timetracking_at(&start, tag) {
|
||||||
Err(e) => trace_error(&e),
|
Err(e) => trace_error(&e),
|
||||||
Ok(entry) => {
|
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)
|
trace_error(&e)
|
||||||
} else {
|
} else {
|
||||||
debug!("Setting end time worked: {:?}", elem);
|
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)
|
::std::process::exit(exit_code)
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn start(rt: &Runtime) -> i32 {
|
||||||
1
|
1
|
||||||
},
|
},
|
||||||
Ok(entry) => {
|
Ok(entry) => {
|
||||||
let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
|
rt.report_touched(entry.get_location()).unwrap_or_exit();
|
||||||
|
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,17 +60,11 @@ pub fn stop(rt: &Runtime) -> i32 {
|
||||||
.get_timetrackings()
|
.get_timetrackings()
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.trace_unwrap()
|
.trace_unwrap()
|
||||||
.filter_map(|tracking| {
|
.filter(|tracking| {
|
||||||
let is_none = tracking
|
tracking
|
||||||
.get_end_datetime()
|
.get_end_datetime()
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.is_none();
|
.is_none()
|
||||||
|
|
||||||
if is_none {
|
|
||||||
Some(tracking)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|t| t.get_timetrack_tag())
|
.map(|t| t.get_timetrack_tag())
|
||||||
.map(|r| r.map_err_trace_exit_unwrap())
|
.map(|r| r.map_err_trace_exit_unwrap())
|
||||||
|
@ -99,7 +93,7 @@ pub fn stop(rt: &Runtime) -> i32 {
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
debug!("Setting end time worked: {:?}", elem);
|
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
|
acc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ use libimagerror::exit::ExitUnwrap;
|
||||||
use libimagtimetrack::tag::TimeTrackingTag;
|
use libimagtimetrack::tag::TimeTrackingTag;
|
||||||
use libimagtimetrack::store::TimeTrackStore;
|
use libimagtimetrack::store::TimeTrackStore;
|
||||||
|
|
||||||
const DATE_TIME_PARSE_FMT : &'static str = "%Y-%m-%dT%H:%M:%S";
|
const DATE_TIME_PARSE_FMT : &str = "%Y-%m-%dT%H:%M:%S";
|
||||||
const DATE_PARSE_FMT : &'static str = "%Y-%m-%d";
|
const DATE_PARSE_FMT : &str = "%Y-%m-%d";
|
||||||
|
|
||||||
pub fn track(rt: &Runtime) -> i32 {
|
pub fn track(rt: &Runtime) -> i32 {
|
||||||
let (_, cmd) = rt.cli().subcommand();
|
let (_, cmd) = rt.cli().subcommand();
|
||||||
|
@ -87,7 +87,7 @@ pub fn track(rt: &Runtime) -> i32 {
|
||||||
1
|
1
|
||||||
},
|
},
|
||||||
Ok(entry) => {
|
Ok(entry) => {
|
||||||
let _ = rt.report_touched(entry.get_location()).unwrap_or_exit();
|
rt.report_touched(entry.get_location()).unwrap_or_exit();
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub fn week(rt: &Runtime) -> i32 {
|
||||||
|
|
||||||
let tags = cmd
|
let tags = cmd
|
||||||
.values_of("tags")
|
.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| {
|
let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
|
||||||
start <= *dt
|
start <= *dt
|
||||||
|
@ -117,7 +117,7 @@ pub fn week(rt: &Runtime) -> i32 {
|
||||||
let end = e.get_end_datetime()?;
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
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))
|
Ok((tag, start, end))
|
||||||
})
|
})
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub fn year(rt: &Runtime) -> i32 {
|
||||||
|
|
||||||
let tags = cmd
|
let tags = cmd
|
||||||
.values_of("tags")
|
.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| {
|
let start_time_filter = has_start_time_where(move |dt: &NaiveDateTime| {
|
||||||
start <= *dt
|
start <= *dt
|
||||||
|
@ -117,7 +117,7 @@ pub fn year(rt: &Runtime) -> i32 {
|
||||||
let end = e.get_end_datetime()?;
|
let end = e.get_end_datetime()?;
|
||||||
debug!(" -> end = {:?}", end);
|
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))
|
Ok((tag, start, end))
|
||||||
})
|
})
|
||||||
|
|
|
@ -97,7 +97,7 @@ fn tw_hook(rt: &Runtime) {
|
||||||
.import_task_from_reader(stdin)
|
.import_task_from_reader(stdin)
|
||||||
.map_err_trace_exit_unwrap();
|
.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()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ fn list(rt: &Runtime) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// and then print that
|
// 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();
|
res.map_err_trace().ok();
|
||||||
|
|
|
@ -97,7 +97,7 @@ fn list(rt: &Runtime, wiki_name: &str) {
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.trace_unwrap_exit()
|
.trace_unwrap_exit()
|
||||||
.for_each(|id| {
|
.for_each(|id| {
|
||||||
let _ = writeln!(outlock, "{}{}", prefix, id)
|
writeln!(outlock, "{}{}", prefix, id)
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.unwrap_or_exit();
|
||||||
});
|
});
|
||||||
|
@ -114,7 +114,7 @@ fn idof(rt: &Runtime, wiki_name: &str) {
|
||||||
let out = rt.stdout();
|
let out = rt.stdout();
|
||||||
let mut lock = out.lock();
|
let mut lock = out.lock();
|
||||||
|
|
||||||
let _ = rt.store()
|
rt.store()
|
||||||
.get_wiki(wiki_name)
|
.get_wiki(wiki_name)
|
||||||
.map_err_trace_exit_unwrap()
|
.map_err_trace_exit_unwrap()
|
||||||
.unwrap_or_else(|| {
|
.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-noedit") {
|
||||||
if scmd.is_present("create-editheader") {
|
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 {
|
} 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_warn_err_str("Linking has failed. Trying to safe the entry now. Please investigate by hand if this succeeds.")
|
||||||
.map_err(|e| {
|
.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
|
e
|
||||||
})
|
})
|
||||||
.map_warn_err_str("Safed entry")
|
.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()
|
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) {
|
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 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 (_, 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) {
|
fn show(rt: &Runtime, wiki_name: &str) {
|
||||||
|
@ -249,7 +249,7 @@ fn show(rt: &Runtime, wiki_name: &str) {
|
||||||
.to_exit_code()
|
.to_exit_code()
|
||||||
.unwrap_or_exit();
|
.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();
|
.map_err_trace_exit_unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = wiki
|
wiki
|
||||||
.delete_entry(&name)
|
.delete_entry(&name)
|
||||||
.map_err_trace_exit_unwrap();
|
.map_err_trace_exit_unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,19 +35,19 @@ impl<'a, T: 'a + ?Sized> ImagTrace<'a, T> {
|
||||||
impl<'a> Display for ImagTrace<'a, Error>
|
impl<'a> Display for ImagTrace<'a, Error>
|
||||||
{
|
{
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
|
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() {
|
for (i, cause) in self.0.iter_causes().enumerate() {
|
||||||
let _ = writeln!(fmt,
|
writeln!(fmt,
|
||||||
"{prefix}: {error}",
|
"{prefix}: {error}",
|
||||||
prefix = Red.blink().paint(format!("ERROR[{:>4}]", i + 1)),
|
prefix = Red.blink().paint(format!("ERROR[{:>4}]", i + 1)),
|
||||||
error = cause)?;
|
error = cause)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?;
|
writeln!(fmt, "{}", Red.paint("--- BACKTRACE ---"))?;
|
||||||
let _ = writeln!(fmt, "{:?}", self.0.backtrace())?;
|
writeln!(fmt, "{:?}", self.0.backtrace())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,11 +56,11 @@ pub fn fetch_config(searchpath: &PathBuf) -> Result<Option<Value>> {
|
||||||
|
|
||||||
env::var("HOME")
|
env::var("HOME")
|
||||||
.map(|home| gen_vars(&PathBuf::from(home), variants.iter(), &modifier))
|
.map(|home| gen_vars(&PathBuf::from(home), variants.iter(), &modifier))
|
||||||
.unwrap_or(vec![]),
|
.unwrap_or_else(|_| vec![]),
|
||||||
|
|
||||||
xdg_basedir::get_data_home()
|
xdg_basedir::get_data_home()
|
||||||
.map(|data_dir| gen_vars(&data_dir, variants.iter(), &modifier))
|
.map(|data_dir| gen_vars(&data_dir, variants.iter(), &modifier))
|
||||||
.unwrap_or(vec![]),
|
.unwrap_or_else(|_| vec![]),
|
||||||
];
|
];
|
||||||
|
|
||||||
let config = vals
|
let config = vals
|
||||||
|
@ -121,10 +121,10 @@ pub fn override_config(val: &mut Value, v: Vec<String>) -> Result<()> {
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
let value = val.read_mut(&k)
|
let value = val.read_mut(&k)
|
||||||
.context(EM::TomlQueryError)?
|
.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)
|
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);
|
info!("Successfully overridden: {} = {}", k, new_value);
|
||||||
*value = new_value;
|
*value = new_value;
|
||||||
|
|
|
@ -90,18 +90,18 @@ impl ImagLogger {
|
||||||
|
|
||||||
{
|
{
|
||||||
use self::log_lvl_aggregate::*;
|
use self::log_lvl_aggregate::*;
|
||||||
let _ = aggregate::<Trace>(&mut handlebars, config, "TRACE")?;
|
aggregate::<Trace>(&mut handlebars, config, "TRACE")?;
|
||||||
let _ = aggregate::<Debug>(&mut handlebars, config, "DEBUG")?;
|
aggregate::<Debug>(&mut handlebars, config, "DEBUG")?;
|
||||||
let _ = aggregate::<Info>(&mut handlebars, config, "INFO")?;
|
aggregate::<Info>(&mut handlebars, config, "INFO")?;
|
||||||
let _ = aggregate::<Warn>(&mut handlebars, config, "WARN")?;
|
aggregate::<Warn>(&mut handlebars, config, "WARN")?;
|
||||||
let _ = aggregate::<Error>(&mut handlebars, config, "ERROR")?;
|
aggregate::<Error>(&mut handlebars, config, "ERROR")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ImagLogger {
|
Ok(ImagLogger {
|
||||||
global_loglevel : aggregate_global_loglevel(matches, config)?,
|
global_loglevel : aggregate_global_loglevel(matches, config)?,
|
||||||
global_destinations : aggregate_global_destinations(config)?,
|
global_destinations : aggregate_global_destinations(config)?,
|
||||||
module_settings : aggregate_module_settings(matches, config)?,
|
module_settings : aggregate_module_settings(matches, config)?,
|
||||||
handlebars : handlebars,
|
handlebars,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,17 +138,17 @@ impl Log for ImagLogger {
|
||||||
.render(&format!("{}", record.level()), &data)
|
.render(&format!("{}", record.level()), &data)
|
||||||
.unwrap_or_else(|e| format!("Failed rendering logging data: {:?}\n", e));
|
.unwrap_or_else(|e| format!("Failed rendering logging data: {:?}\n", e));
|
||||||
|
|
||||||
let log_to_destination = |d: &LogDestination| match d {
|
let log_to_destination = |d: &LogDestination| match *d {
|
||||||
&LogDestination::Stderr => {
|
LogDestination::Stderr => {
|
||||||
let _ = write!(stderr(), "{}\n", logtext);
|
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.
|
// if there is an error in the lock, we cannot do anything. So we ignore it here.
|
||||||
let _ = arc_mutex_logdest
|
let _ = arc_mutex_logdest
|
||||||
.deref()
|
.deref()
|
||||||
.lock()
|
.lock()
|
||||||
.map(|mut logdest| {
|
.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();
|
module_setting.level.unwrap_or(self.global_loglevel) >= record.level();
|
||||||
|
|
||||||
if set {
|
if set {
|
||||||
module_setting.destinations.as_ref().map(|destinations| for d in destinations {
|
if let Some(destinations) = &module_setting.destinations {
|
||||||
// If there's an error, we cannot do anything, can we?
|
for d in destinations {
|
||||||
let _ = log_to_destination(&d);
|
// If there's an error, we cannot do anything, can we?
|
||||||
});
|
log_to_destination(&d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for d in self.global_destinations.iter() {
|
for d in self.global_destinations.iter() {
|
||||||
// If there's an error, we cannot do anything, can we?
|
// 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
|
// Yes, we log
|
||||||
for d in self.global_destinations.iter() {
|
for d in self.global_destinations.iter() {
|
||||||
// If there's an error, we cannot do anything, can we?
|
// 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),
|
"info" => Ok(Level::Info),
|
||||||
"warn" => Ok(Level::Warn),
|
"warn" => Ok(Level::Warn),
|
||||||
"error" => Ok(Level::Error),
|
"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")
|
.read_string("imag.logging.level")
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.context(EM::TomlQueryError)?
|
.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))?;
|
.and_then(|s| match_log_level_str(&s))?;
|
||||||
|
|
||||||
if let Some(cli_loglevel) = get_arg_loglevel(matches)? {
|
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()
|
raw.iter()
|
||||||
.map(|val| {
|
.map(|val| {
|
||||||
val.as_str()
|
val.as_str()
|
||||||
|
@ -287,9 +289,9 @@ fn aggregate_global_destinations(config: Option<&Value>)
|
||||||
.as_array()
|
.as_array()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
let msg = "Type error at 'imag.logging.destinations', expected 'Array'";
|
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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,8 +153,8 @@ impl<'a> Runtime<'a> {
|
||||||
store_result.map(|store| Runtime {
|
store_result.map(|store| Runtime {
|
||||||
cli_matches: matches,
|
cli_matches: matches,
|
||||||
configuration: config,
|
configuration: config,
|
||||||
rtp: rtp,
|
rtp,
|
||||||
store: store,
|
store,
|
||||||
|
|
||||||
has_output_pipe,
|
has_output_pipe,
|
||||||
has_input_pipe,
|
has_input_pipe,
|
||||||
|
@ -381,14 +381,14 @@ impl<'a> Runtime<'a> {
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
self.config()
|
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")? {
|
.and_then(|v| match v.read("rt.editor")? {
|
||||||
Some(&Value::String(ref s)) => Ok(Some(s.clone())),
|
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),
|
None => Ok(None),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.or(env::var("EDITOR"))
|
.or_else(|_| env::var("EDITOR"))
|
||||||
.map_err(|_| Error::from(EM::IO))
|
.map_err(|_| Error::from(EM::IO))
|
||||||
.map_dbg(|s| format!("Editing with '{}'", s))
|
.map_dbg(|s| format!("Editing with '{}'", s))
|
||||||
.and_then(|s| {
|
.and_then(|s| {
|
||||||
|
@ -617,13 +617,13 @@ fn get_override_specs(matches: &ArgMatches) -> Vec<String> {
|
||||||
.map(|values| {
|
.map(|values| {
|
||||||
values
|
values
|
||||||
.filter(|s| {
|
.filter(|s| {
|
||||||
let b = s.contains("=");
|
let b = s.contains('=');
|
||||||
if !b { warn!("override '{}' does not contain '=' - will be ignored!", s); }
|
if !b { warn!("override '{}' does not contain '=' - will be ignored!", s); }
|
||||||
b
|
b
|
||||||
})
|
})
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.unwrap_or(vec![])
|
.unwrap_or_else(|| vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl FileAbstraction for FSFileAbstraction {
|
||||||
if let Some(p) = to.parent() {
|
if let Some(p) = to.parent() {
|
||||||
if !p.exists() {
|
if !p.exists() {
|
||||||
debug!("Creating: {:?}", p);
|
debug!("Creating: {:?}", p);
|
||||||
let _ = create_dir_all(&p).context(EM::DirNotCreated)?;
|
create_dir_all(&p).context(EM::DirNotCreated)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("Failed to find parent. This looks like it will fail now");
|
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>> {
|
fn open_file<A: AsRef<Path>>(p: A) -> ::std::io::Result<Option<File>> {
|
||||||
match OpenOptions::new().write(true).read(true).open(p) {
|
match OpenOptions::new().write(true).read(true).open(p) {
|
||||||
Err(e) => match e.kind() {
|
Err(e) => match e.kind() {
|
||||||
::std::io::ErrorKind::NotFound => return Ok(None),
|
::std::io::ErrorKind::NotFound => Ok(None),
|
||||||
_ => return Err(e),
|
_ => Err(e),
|
||||||
},
|
},
|
||||||
Ok(file) => Ok(Some(file))
|
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());
|
trace!("'{}' is directory = {}", parent.display(), parent.is_dir());
|
||||||
if !parent.is_dir() {
|
if !parent.is_dir() {
|
||||||
trace!("Implicitely creating directory: {:?}", parent);
|
trace!("Implicitely creating directory: {:?}", parent);
|
||||||
let _ = create_dir_all(parent)?;
|
create_dir_all(parent)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OpenOptions::new().write(true).read(true).create(true).open(p)
|
OpenOptions::new().write(true).read(true).create(true).open(p)
|
||||||
|
|
|
@ -79,14 +79,11 @@ impl FileAbstractionInstance for InMemoryFileAbstractionInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_file_content(&mut self, buf: &Entry) -> Result<()> {
|
fn write_file_content(&mut self, buf: &Entry) -> Result<()> {
|
||||||
match *self {
|
let absent_path = &self.absent_path;
|
||||||
InMemoryFileAbstractionInstance { ref absent_path, .. } => {
|
let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed");
|
||||||
let mut mtx = self.fs_abstraction.lock().expect("Locking Mutex failed");
|
let backend = mtx.get_mut();
|
||||||
let backend = mtx.get_mut();
|
let _ = backend.insert(absent_path.clone(), buf.clone());
|
||||||
let _ = backend.insert(absent_path.clone(), buf.clone());
|
Ok(())
|
||||||
return Ok(());
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +98,11 @@ impl InMemoryFileAbstraction {
|
||||||
&self.virtual_filesystem
|
&self.virtual_filesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backend_cloned<'a>(&'a self) -> Result<HashMap<PathBuf, Entry>> {
|
fn backend_cloned(&self) -> Result<HashMap<PathBuf, Entry>> {
|
||||||
self.virtual_filesystem
|
self.virtual_filesystem
|
||||||
.lock()
|
.lock()
|
||||||
.map_err(|_| Error::from(EM::LockError))
|
.map_err(|_| Error::from(EM::LockError))
|
||||||
.map(|mtx| mtx.deref().borrow().clone())
|
.map(|mtx| mtx.deref().borrow().clone())
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -172,7 +168,7 @@ impl FileAbstraction for InMemoryFileAbstraction {
|
||||||
self.backend_cloned().map(Drain::new)
|
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);
|
debug!("Draining into : {:?}", self);
|
||||||
let mut mtx = self.backend()
|
let mut mtx = self.backend()
|
||||||
.lock()
|
.lock()
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub(crate) trait FileAbstraction : Debug {
|
||||||
fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance>;
|
fn new_instance(&self, p: PathBuf) -> Box<dyn FileAbstractionInstance>;
|
||||||
|
|
||||||
fn drain(&self) -> Result<Drain>;
|
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>>;
|
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())
|
Drain::new(HashMap::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter<'a>(&'a mut self) -> DrainIter<'a> {
|
pub fn iter(&mut self) -> DrainIter<'_> {
|
||||||
DrainIter(self.0.drain())
|
DrainIter(self.0.drain())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,6 @@ pub struct Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
|
|
||||||
/// Create a new Store object
|
/// Create a new Store object
|
||||||
///
|
///
|
||||||
/// This opens a Store in `location`. The store_config is used to check whether creating the
|
/// 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 {
|
let store = Store {
|
||||||
location: location.clone(),
|
location: location.clone(),
|
||||||
entries: Arc::new(RwLock::new(HashMap::new())),
|
entries: Arc::new(RwLock::new(HashMap::new())),
|
||||||
backend: backend,
|
backend,
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Store building succeeded");
|
debug!("Store building succeeded");
|
||||||
|
@ -491,7 +490,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Seems like {:?} is on the FS", pb);
|
debug!("Seems like {:?} is on the FS", pb);
|
||||||
let _ = self
|
self
|
||||||
.backend
|
.backend
|
||||||
.remove_file(&pb)
|
.remove_file(&pb)
|
||||||
.context(EM::FileError)
|
.context(EM::FileError)
|
||||||
|
@ -608,7 +607,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
debug!("New entry does not yet exist on filesystem. Good.");
|
debug!("New entry does not yet exist on filesystem. Good.");
|
||||||
|
|
||||||
let _ = self
|
self
|
||||||
.backend
|
.backend
|
||||||
.rename(&old_id_pb, &new_id_pb)
|
.rename(&old_id_pb, &new_id_pb)
|
||||||
.context({
|
.context({
|
||||||
|
@ -621,12 +620,14 @@ impl Store {
|
||||||
|
|
||||||
// assert enforced through check hsmap.contains_key(&new_id) above.
|
// assert enforced through check hsmap.contains_key(&new_id) above.
|
||||||
// Should therefor never fail
|
// Should therefor never fail
|
||||||
assert!(hsmap
|
let hsmap_does_not_have_key = hsmap
|
||||||
.remove(&old_id)
|
.remove(&old_id)
|
||||||
.and_then(|mut entry| {
|
.and_then(|mut entry| {
|
||||||
entry.id = new_id.clone().into();
|
entry.id = new_id.clone();
|
||||||
hsmap.insert(new_id.clone().into(), entry)
|
hsmap.insert(new_id.clone(), entry)
|
||||||
}).is_none())
|
})
|
||||||
|
.is_none();
|
||||||
|
assert!(hsmap_does_not_have_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Moved");
|
debug!("Moved");
|
||||||
|
@ -642,7 +643,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether the store has the Entry pointed to by the StoreId `id`
|
/// 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|
|
let cache_has_entry = |id: &StoreId|
|
||||||
self.entries
|
self.entries
|
||||||
.read()
|
.read()
|
||||||
|
@ -660,7 +661,6 @@ impl Store {
|
||||||
pub fn path(&self) -> &PathBuf {
|
pub fn path(&self) -> &PathBuf {
|
||||||
&self.location
|
&self.location
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Store {
|
impl Debug for Store {
|
||||||
|
@ -986,13 +986,13 @@ mod test {
|
||||||
assert!(has_imag_version_in_main_section(&Value::Table(map)).is_err());
|
assert!(has_imag_version_in_main_section(&Value::Table(map)).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
static TEST_ENTRY : &'static str = "---
|
static TEST_ENTRY : &str = "---
|
||||||
[imag]
|
[imag]
|
||||||
version = '0.0.3'
|
version = '0.0.3'
|
||||||
---
|
---
|
||||||
Hai";
|
Hai";
|
||||||
|
|
||||||
static TEST_ENTRY_TNL : &'static str = "---
|
static TEST_ENTRY_TNL : &str = "---
|
||||||
[imag]
|
[imag]
|
||||||
version = '0.0.3'
|
version = '0.0.3'
|
||||||
---
|
---
|
||||||
|
@ -1129,14 +1129,12 @@ mod store_tests {
|
||||||
|
|
||||||
for n in 1..100 {
|
for n in 1..100 {
|
||||||
let s = format!("test-{}", n % 50);
|
let s = format!("test-{}", n % 50);
|
||||||
store.create(PathBuf::from(s.clone()))
|
if let Ok(entry) = store.create(PathBuf::from(s.clone())) {
|
||||||
.ok()
|
assert!(entry.verify().is_ok());
|
||||||
.map(|entry| {
|
let loc = entry.get_location().clone().with_base(store.path()).into_pathbuf().unwrap();
|
||||||
assert!(entry.verify().is_ok());
|
assert!(loc.starts_with("/"));
|
||||||
let loc = entry.get_location().clone().with_base(store.path()).into_pathbuf().unwrap();
|
assert!(loc.ends_with(s));
|
||||||
assert!(loc.starts_with("/"));
|
}
|
||||||
assert!(loc.ends_with(s));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,8 +1174,8 @@ mod store_tests {
|
||||||
|
|
||||||
for n in 1..100 {
|
for n in 1..100 {
|
||||||
match store.get(PathBuf::from(format!("test-{}", n))) {
|
match store.get(PathBuf::from(format!("test-{}", n))) {
|
||||||
Ok(None) => assert!(true),
|
Ok(None) => {},
|
||||||
_ => assert!(false),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1188,8 +1186,8 @@ mod store_tests {
|
||||||
|
|
||||||
for n in 1..100 {
|
for n in 1..100 {
|
||||||
match store.delete(PathBuf::from(format!("test-{}", n))) {
|
match store.delete(PathBuf::from(format!("test-{}", n))) {
|
||||||
Err(_) => assert!(true),
|
Err(_) => {},
|
||||||
_ => assert!(false),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,4 +1235,3 @@ mod store_tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
StoreIdWithBase(base, self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ impl StoreIdIterator {
|
||||||
StoreIdIterator { iter }
|
StoreIdIterator { iter }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_store<'a>(self, store: &'a Store) -> StoreIdIteratorWithStore<'a> {
|
pub fn with_store(self, store: &Store) -> StoreIdIteratorWithStore<'_> {
|
||||||
StoreIdIteratorWithStore(self, store)
|
StoreIdIteratorWithStore(self, store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,11 +55,11 @@ pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> {
|
||||||
header_consumed = true;
|
header_consumed = true;
|
||||||
// do not further process the line
|
// do not further process the line
|
||||||
} else if !header_consumed {
|
} else if !header_consumed {
|
||||||
let _ = writeln!(header, "{}", line).context(EM::FormatError)?;
|
writeln!(header, "{}", line).context(EM::FormatError)?;
|
||||||
} else if iter.peek().is_some() {
|
} else if iter.peek().is_some() {
|
||||||
let _ = writeln!(content, "{}", line).context(EM::FormatError)?;
|
writeln!(content, "{}", line).context(EM::FormatError)?;
|
||||||
} else {
|
} else {
|
||||||
let _ = write!(content, "{}", line).context(EM::FormatError)?;
|
write!(content, "{}", line).context(EM::FormatError)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ pub trait BookmarkCollectionStore<'a> {
|
||||||
|
|
||||||
impl<'a> BookmarkCollectionStore<'a> for Store {
|
impl<'a> BookmarkCollectionStore<'a> for Store {
|
||||||
|
|
||||||
|
#[allow(clippy::new_ret_no_self)]
|
||||||
fn new(&'a self, name: &str) -> Result<FileLockEntry<'a>> {
|
fn new(&'a self, name: &str) -> Result<FileLockEntry<'a>> {
|
||||||
crate::module_path::new_id(name)
|
crate::module_path::new_id(name)
|
||||||
.and_then(|id| self.create(id)
|
.and_then(|id| self.create(id)
|
||||||
|
@ -94,6 +95,7 @@ impl BookmarkCollection for Entry {
|
||||||
self.get_urls(store)
|
self.get_urls(store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::redundant_closure)]
|
||||||
fn link_entries(&self) -> Result<Vec<StoreLink>> {
|
fn link_entries(&self) -> Result<Vec<StoreLink>> {
|
||||||
use libimagentryurl::util::is_external_link_storeid;
|
use libimagentryurl::util::is_external_link_storeid;
|
||||||
self.links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
|
self.links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
|
||||||
|
@ -119,7 +121,6 @@ impl BookmarkCollection for Entry {
|
||||||
pub mod iter {
|
pub mod iter {
|
||||||
use crate::link::Link;
|
use crate::link::Link;
|
||||||
use failure::Fallible as Result;
|
use failure::Fallible as Result;
|
||||||
use failure::Error;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use libimagentryurl::iter::UrlIter;
|
use libimagentryurl::iter::UrlIter;
|
||||||
|
@ -162,7 +163,7 @@ pub mod iter {
|
||||||
loop {
|
loop {
|
||||||
let n = match self.0.next() {
|
let n = match self.0.next() {
|
||||||
Some(Ok(n)) => n,
|
Some(Ok(n)) => n,
|
||||||
Some(Err(e)) => return Some(Err(Error::from(e))),
|
Some(Err(e)) => return Some(Err(e)),
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ fn prepare_fetching_from_store(buf: &str) -> Result<(StoreId, Value)> {
|
||||||
debug!("Parsed: {:?}", vcard);
|
debug!("Parsed: {:?}", vcard);
|
||||||
|
|
||||||
let uid = vcard.uid()
|
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 value = { // dirty ugly hack
|
||||||
let serialized = DeserVcard::from(vcard);
|
let serialized = DeserVcard::from(vcard);
|
||||||
|
|
|
@ -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 id = DiaryId::new(String::from(diary_name), ndt.year(), ndt.month(), ndt.day(), 0, 0, 0);
|
||||||
|
|
||||||
let mut entry = self.retrieve(id)?;
|
let mut entry = self.retrieve(id)?;
|
||||||
let _ = entry.set_isflag::<IsDiaryEntry>()?;
|
entry.set_isflag::<IsDiaryEntry>()?;
|
||||||
Ok(entry)
|
Ok(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ impl Diary for Store {
|
||||||
ndt.second());
|
ndt.second());
|
||||||
|
|
||||||
let mut entry = self.retrieve(id)?;
|
let mut entry = self.retrieve(id)?;
|
||||||
let _ = entry.set_isflag::<IsDiaryEntry>()?;
|
entry.set_isflag::<IsDiaryEntry>()?;
|
||||||
Ok(entry)
|
Ok(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,6 @@ impl Diary for Store {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_iter()
|
|
||||||
.rev()
|
.rev()
|
||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl DiaryId {
|
||||||
|
|
||||||
pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32, sec: u32) -> DiaryId {
|
pub fn new(name: String, y: i32, m: u32, d: u32, h: u32, min: u32, sec: u32) -> DiaryId {
|
||||||
DiaryId {
|
DiaryId {
|
||||||
name: name,
|
name,
|
||||||
year: y,
|
year: y,
|
||||||
month: m,
|
month: m,
|
||||||
day: d,
|
day: d,
|
||||||
|
@ -202,7 +202,7 @@ fn component_to_str<'a>(com: Component<'a>) -> Result<&'a str> {
|
||||||
Component::Normal(s) => Some(s),
|
Component::Normal(s) => Some(s),
|
||||||
_ => None,
|
_ => None,
|
||||||
}.and_then(|s| s.to_str())
|
}.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 {
|
impl FromStoreId for DiaryId {
|
||||||
|
@ -215,7 +215,7 @@ impl FromStoreId for DiaryId {
|
||||||
|
|
||||||
fn next_component<'a>(components: &'a mut Rev<Components>) -> Result<&'a str> {
|
fn next_component<'a>(components: &'a mut Rev<Components>) -> Result<&'a str> {
|
||||||
components.next()
|
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)
|
.and_then(component_to_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ impl FromStoreId for DiaryId {
|
||||||
trace!("Found components: {:?}", cmps);
|
trace!("Found components: {:?}", cmps);
|
||||||
|
|
||||||
let (hour, minute, second) = next_component(&mut cmps).and_then(|time| {
|
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 hour = time.next().and_then(|s| FromStr::from_str(s).ok());
|
||||||
let minute = 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());
|
let second = time.next().and_then(|s| FromStr::from_str(s).ok());
|
||||||
|
@ -235,7 +235,7 @@ impl FromStoreId for DiaryId {
|
||||||
|
|
||||||
match (hour, minute, second) {
|
match (hour, minute, second) {
|
||||||
(Some(h), Some(m), Some(s)) => Ok((h, m, s)),
|
(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")),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ use libimagstore::storeid::StoreId;
|
||||||
|
|
||||||
use crate::is_in_diary::IsInDiary;
|
use crate::is_in_diary::IsInDiary;
|
||||||
use failure::Fallible as Result;
|
use failure::Fallible as Result;
|
||||||
use failure::Error;
|
|
||||||
use failure::err_msg;
|
use failure::err_msg;
|
||||||
|
|
||||||
/// A iterator for iterating over diary entries
|
/// A iterator for iterating over diary entries
|
||||||
|
@ -54,7 +54,7 @@ impl DiaryEntryIterator {
|
||||||
pub fn new(diaryname: String, iter: StoreIdIterator) -> DiaryEntryIterator {
|
pub fn new(diaryname: String, iter: StoreIdIterator) -> DiaryEntryIterator {
|
||||||
DiaryEntryIterator {
|
DiaryEntryIterator {
|
||||||
name: diaryname,
|
name: diaryname,
|
||||||
iter: iter,
|
iter,
|
||||||
|
|
||||||
year: None,
|
year: None,
|
||||||
month: None,
|
month: None,
|
||||||
|
@ -149,8 +149,8 @@ impl Iterator for DiaryNameIterator {
|
||||||
.and_then(|s| {
|
.and_then(|s| {
|
||||||
s.split("diary/")
|
s.split("diary/")
|
||||||
.nth(1)
|
.nth(1)
|
||||||
.and_then(|n| n.split("/").nth(0).map(String::from))
|
.and_then(|n| n.split('/').nth(0).map(String::from))
|
||||||
.ok_or_else(|| Error::from(err_msg("Error finding diary name")))
|
.ok_or_else(|| err_msg("Error finding diary name"))
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl Viewer for DiaryViewer {
|
||||||
|
|
||||||
for (id, entry) in entries.into_iter() {
|
for (id, entry) in entries.into_iter() {
|
||||||
writeln!(sink, "{} :\n", id)?;
|
writeln!(sink, "{} :\n", id)?;
|
||||||
let _ = self.0.view_entry(entry.deref(), sink)?;
|
self.0.view_entry(entry.deref(), sink)?;
|
||||||
writeln!(sink, "\n---\n")?;
|
writeln!(sink, "\n---\n")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub trait HabitTemplate : Sized {
|
||||||
///
|
///
|
||||||
/// It uses `Store::retrieve()` underneath. So if there is already an instance for the day
|
/// It uses `Store::retrieve()` underneath. So if there is already an instance for the day
|
||||||
/// passed, this will simply return the instance.
|
/// 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>>;
|
-> Result<FileLockEntry<'a>>;
|
||||||
|
|
||||||
/// Shortcut for calling `Self::create_instance_with_date()` with an instance of
|
/// 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>>;
|
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.
|
/// 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>>;
|
-> Result<FileLockEntry<'a>>;
|
||||||
|
|
||||||
/// Same as `HabitTemplate::create_instance_today()` but uses `Store::retrieve` internally.
|
/// 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_comment(&self) -> Result<String>;
|
||||||
fn habit_until_date(&self) -> Result<Option<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
|
/// 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");
|
provide_kindflag_path!(pub IsHabitTemplate, "habit.template.is_habit_template");
|
||||||
|
|
||||||
impl HabitTemplate for Entry {
|
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 name = self.habit_name()?;
|
||||||
let date = date_to_string(date);
|
let date = date_to_string(date);
|
||||||
let id = instance_id_for_name_and_datestr(&name, &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>> {
|
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 name = self.habit_name()?;
|
||||||
let date = date_to_string(date);
|
let date = date_to_string(date);
|
||||||
let id = instance_id_for_name_and_datestr(&name, &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>> {
|
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> {
|
fn linked_instances(&self) -> Result<HabitInstanceStoreIdIterator> {
|
||||||
|
@ -160,11 +160,11 @@ impl HabitTemplate for Entry {
|
||||||
debug!("Increment is {:?}", increment);
|
debug!("Increment is {:?}", increment);
|
||||||
|
|
||||||
let until = self.habit_until_date()?.map(|s| -> Result<_> {
|
let until = self.habit_until_date()?.map(|s| -> Result<_> {
|
||||||
r#try!(date_from_s(s))
|
date_from_s(s)?
|
||||||
.calculate()?
|
.calculate()?
|
||||||
.get_moment()
|
.get_moment()
|
||||||
.map(Clone::clone)
|
.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);
|
debug!("Until-Date is {:?}", basedate);
|
||||||
|
@ -177,7 +177,7 @@ impl HabitTemplate for Entry {
|
||||||
if ndt >= base {
|
if ndt >= base {
|
||||||
debug!("-> {:?} >= {:?}", ndt, base);
|
debug!("-> {:?} >= {:?}", ndt, base);
|
||||||
if let Some(u) = until {
|
if let Some(u) = until {
|
||||||
if ndt > &(u?) {
|
if *ndt > u? {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
} else {
|
} else {
|
||||||
return Ok(Some(ndt.date()));
|
return Ok(Some(ndt.date()));
|
||||||
|
@ -233,7 +233,7 @@ impl HabitTemplate for Entry {
|
||||||
.map(|os| os.map(String::from))
|
.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 name = self.habit_name()?;
|
||||||
let date = date_to_string(date);
|
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))
|
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))
|
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))
|
.context(format_err!("Failed building ID for instance: habit name = {}, habit date = {}", habit_name, habit_date))
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
|
@ -318,7 +318,7 @@ pub mod builder {
|
||||||
pub fn build<'a>(self, store: &'a Store) -> Result<FileLockEntry<'a>> {
|
pub fn build<'a>(self, store: &'a Store) -> Result<FileLockEntry<'a>> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mkerr(s: &'static str) -> Error {
|
fn mkerr(s: &'static str) -> Error {
|
||||||
Error::from(format_err!("Habit builder missing: {}", s))
|
format_err!("Habit builder missing: {}", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = self.name
|
let name = self.name
|
||||||
|
@ -336,7 +336,7 @@ pub mod builder {
|
||||||
if let Some(until) = self.untildate {
|
if let Some(until) = self.untildate {
|
||||||
debug!("Success: Until-Date present");
|
debug!("Success: Until-Date present");
|
||||||
if dateobj > until {
|
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);
|
return Err(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,16 +345,16 @@ pub mod builder {
|
||||||
debug!("Kairos failed: {:?}", e);
|
debug!("Kairos failed: {:?}", e);
|
||||||
return Err(e)
|
return Err(e)
|
||||||
}
|
}
|
||||||
let date = date_to_string(&dateobj);
|
let date = date_to_string(dateobj);
|
||||||
debug!("Success: Date valid");
|
debug!("Success: Date valid");
|
||||||
|
|
||||||
let comment = self.comment.unwrap_or_else(|| String::new());
|
let comment = self.comment.unwrap_or_else(String::new);
|
||||||
let sid = r#try!(build_habit_template_sid(&name));
|
let sid = build_habit_template_sid(&name)?;
|
||||||
|
|
||||||
debug!("Creating entry in store for: {:?}", sid);
|
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 = entry.get_header_mut();
|
||||||
let _ = h.insert("habit.template.name", Value::String(name))?;
|
let _ = h.insert("habit.template.name", Value::String(name))?;
|
||||||
|
@ -364,8 +364,8 @@ pub mod builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(until) = self.untildate {
|
if let Some(until) = self.untildate {
|
||||||
let until = date_to_string(&until);
|
let until = date_to_string(until);
|
||||||
r#try!(entry.get_header_mut().insert("habit.template.until", Value::String(until)));
|
entry.get_header_mut().insert("habit.template.until", Value::String(until))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Success: Created entry in store and set headers");
|
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
|
/// 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)
|
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>>
|
-> Result<FileLockEntry<'a>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let _ = entry.set_isflag::<IsHabitInstance>()?;
|
entry.set_isflag::<IsHabitInstance>()?;
|
||||||
let hdr = entry.get_header_mut();
|
let hdr = entry.get_header_mut();
|
||||||
let _ = hdr.insert("habit.instance.name", Value::String(name))?;
|
let _ = hdr.insert("habit.instance.name", Value::String(name))?;
|
||||||
let _ = hdr.insert("habit.instance.date", Value::String(date))?;
|
let _ = hdr.insert("habit.instance.date", Value::String(date))?;
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub trait HabitInstance {
|
||||||
fn is_habit_instance(&self) -> Result<bool>;
|
fn is_habit_instance(&self) -> Result<bool>;
|
||||||
|
|
||||||
fn get_date(&self) -> Result<NaiveDate>;
|
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_comment(&self, store: &Store) -> Result<String>;
|
||||||
fn get_template_name(&self) -> 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)
|
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;
|
use libimagutil::date::date_to_string;
|
||||||
// Using `set` here because when creating the entry, these headers should be made present.
|
// Using `set` here because when creating the entry, these headers should be made present.
|
||||||
self.get_header_mut()
|
self.get_header_mut()
|
||||||
|
|
|
@ -51,8 +51,7 @@ impl MailConfig {
|
||||||
pub fn account(&self, name: &str) -> Option<&MailAccountConfig> {
|
pub fn account(&self, name: &str) -> Option<&MailAccountConfig> {
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.name == name)
|
.find(|a| a.name == name)
|
||||||
.next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetchcommand(&self) -> &MailCommand {
|
pub fn fetchcommand(&self) -> &MailCommand {
|
||||||
|
@ -74,8 +73,7 @@ impl MailConfig {
|
||||||
pub fn fetchcommand_for_account(&self, account_name: &str) -> &MailCommand {
|
pub fn fetchcommand_for_account(&self, account_name: &str) -> &MailCommand {
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.name == account_name)
|
.find(|a| a.name == account_name)
|
||||||
.next()
|
|
||||||
.and_then(|a| a.fetchcommand.as_ref())
|
.and_then(|a| a.fetchcommand.as_ref())
|
||||||
.unwrap_or_else(|| self.fetchcommand())
|
.unwrap_or_else(|| self.fetchcommand())
|
||||||
}
|
}
|
||||||
|
@ -83,8 +81,7 @@ impl MailConfig {
|
||||||
pub fn postfetchcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
|
pub fn postfetchcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.name == account_name)
|
.find(|a| a.name == account_name)
|
||||||
.next()
|
|
||||||
.and_then(|a| a.postfetchcommand.as_ref())
|
.and_then(|a| a.postfetchcommand.as_ref())
|
||||||
.or_else(|| self.postfetchcommand())
|
.or_else(|| self.postfetchcommand())
|
||||||
}
|
}
|
||||||
|
@ -92,8 +89,7 @@ impl MailConfig {
|
||||||
pub fn sendcommand_for_account(&self, account_name: &str) -> &MailCommand {
|
pub fn sendcommand_for_account(&self, account_name: &str) -> &MailCommand {
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.name == account_name)
|
.find(|a| a.name == account_name)
|
||||||
.next()
|
|
||||||
.and_then(|a| a.sendcommand.as_ref())
|
.and_then(|a| a.sendcommand.as_ref())
|
||||||
.unwrap_or_else(|| self.sendcommand())
|
.unwrap_or_else(|| self.sendcommand())
|
||||||
}
|
}
|
||||||
|
@ -101,8 +97,7 @@ impl MailConfig {
|
||||||
pub fn postsendcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
|
pub fn postsendcommand_for_account(&self, account_name: &str) -> Option<&MailCommand> {
|
||||||
self.accounts()
|
self.accounts()
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|a| a.name == account_name)
|
.find(|a| a.name == account_name)
|
||||||
.next()
|
|
||||||
.and_then(|a| a.postsendcommand.as_ref())
|
.and_then(|a| a.postsendcommand.as_ref())
|
||||||
.or_else(|| self.postsendcommand())
|
.or_else(|| self.postsendcommand())
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl<'a> MailStore<'a> for Store {
|
||||||
let new_sid = crate::module_path::new_id(message_id.clone())?;
|
let new_sid = crate::module_path::new_id(message_id.clone())?;
|
||||||
|
|
||||||
let mut entry = self.create(new_sid)?;
|
let mut entry = self.create(new_sid)?;
|
||||||
let _ = entry
|
entry
|
||||||
.as_ref_with_hasher_mut::<MailHasher>()
|
.as_ref_with_hasher_mut::<MailHasher>()
|
||||||
.make_ref(p, collection_name, config, false)?;
|
.make_ref(p, collection_name, config, false)?;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ impl<'a> MailStore<'a> for Store {
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.insert("mail.message-id", Value::String(message_id))?;
|
.insert("mail.message-id", Value::String(message_id))?;
|
||||||
|
|
||||||
let _ = entry
|
entry
|
||||||
.as_ref_with_hasher_mut::<DefaultHasher>()
|
.as_ref_with_hasher_mut::<DefaultHasher>()
|
||||||
.make_ref(p, collection_name, config, false)?;
|
.make_ref(p, collection_name, config, false)?;
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
//
|
//
|
||||||
|
|
||||||
pub const CRATE_NAME : &'static str = "timetrack";
|
pub const CRATE_NAME : &str = "timetrack";
|
||||||
pub const DATE_TIME_FORMAT : &'static str = "%Y-%m-%dT%H:%M:%S";
|
pub const DATE_TIME_FORMAT : &str = "%Y-%m-%dT%H:%M:%S";
|
||||||
pub const DATE_TIME_START_HEADER_PATH : &'static str = "timetrack.start";
|
pub const DATE_TIME_START_HEADER_PATH : &str = "timetrack.start";
|
||||||
pub const DATE_TIME_END_HEADER_PATH : &'static str = "timetrack.end";
|
pub const DATE_TIME_END_HEADER_PATH : &str = "timetrack.end";
|
||||||
pub const DATE_TIME_TAG_HEADER_PATH : &'static str = "timetrack.tag";
|
pub const DATE_TIME_TAG_HEADER_PATH : &str = "timetrack.tag";
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ impl<'a> CreateTimeTrackIter<'a>
|
||||||
{
|
{
|
||||||
pub fn new(inner: TagStoreIdIter, store: &'a Store) -> CreateTimeTrackIter<'a> {
|
pub fn new(inner: TagStoreIdIter, store: &'a Store) -> CreateTimeTrackIter<'a> {
|
||||||
CreateTimeTrackIter {
|
CreateTimeTrackIter {
|
||||||
inner: inner,
|
inner,
|
||||||
store: store,
|
store,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub fn has_end_time_where<F>(f: F) -> HasEndTimeWhere<F>
|
||||||
HasEndTimeWhere::new(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)
|
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> {
|
impl<'a> HasOneOfTags<'a> {
|
||||||
pub fn new(tags: &'a Vec<TTT>) -> HasOneOfTags<'a> {
|
pub fn new(tags: &'a [TTT]) -> HasOneOfTags<'a> {
|
||||||
HasOneOfTags(tags)
|
HasOneOfTags(tags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl TagStoreIdIter {
|
||||||
TagStoreIdIter { inner, datetime }
|
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)
|
CreateTimeTrackIter::new(self, store)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ impl Iterator for TagStoreIdIter {
|
||||||
let id_str = format!("{}-{}", dt, tag.as_str());
|
let id_str = format!("{}-{}", dt, tag.as_str());
|
||||||
crate::module_path::new_id(id_str)
|
crate::module_path::new_id(id_str)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map(|id| (id, self.datetime.clone()))
|
.map(|id| (id, self.datetime))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
use chrono::naive::NaiveDateTime as NDT;
|
use chrono::naive::NaiveDateTime as NDT;
|
||||||
use failure::Fallible as Result;
|
use failure::Fallible as Result;
|
||||||
use failure::Error;
|
|
||||||
use failure::err_msg;
|
use failure::err_msg;
|
||||||
|
|
||||||
use crate::tag::TimeTrackingTag as TTT;
|
use crate::tag::TimeTrackingTag as TTT;
|
||||||
|
@ -48,7 +48,7 @@ impl Iterator for TagIter {
|
||||||
.map(|t| if is_tag_str(&t).is_ok() {
|
.map(|t| if is_tag_str(&t).is_ok() {
|
||||||
Ok(TTT::from(t))
|
Ok(TTT::from(t))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::from(err_msg("Error in Tag format")))
|
Err(err_msg("Error in Tag format"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
.context(err_msg("Error importing"))
|
.context(err_msg("Error importing"))
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.and_then(|t| {
|
.and_then(|t| {
|
||||||
let uuid = t.uuid().clone();
|
let uuid = *t.uuid();
|
||||||
self.new_from_twtask(t).map(|t| (t, line, 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())
|
import_task(s.as_str())
|
||||||
.context(err_msg("Import error"))
|
.context(err_msg("Import error"))
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.map(|t| t.uuid().clone())
|
.map(|t| *t.uuid())
|
||||||
.and_then(|uuid| self.get_task_from_uuid(uuid))
|
.and_then(|uuid| self.get_task_from_uuid(uuid))
|
||||||
.and_then(|o| match o {
|
.and_then(|o| match o {
|
||||||
None => Ok(Err(s)),
|
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
|
// Here we check if the status of a task is deleted and if yes, we delete it
|
||||||
// from the store.
|
// from the store.
|
||||||
if *ttask.status() == TaskStatus::Deleted {
|
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());
|
info!("Deleted task {}", *ttask.uuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ impl<'a> TaskStore<'a> for Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_tasks(&self) -> Result<TaskIdIterator> {
|
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>> {
|
fn new_from_twtask(&'a self, task: TTask) -> Result<FileLockEntry<'a>> {
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl WikiStore for Store {
|
||||||
|
|
||||||
/// get a wiki by its name
|
/// get a wiki by its name
|
||||||
fn get_wiki<'a, 'b>(&'a self, name: &'b str) -> Result<Option<Wiki<'a, 'b>>> {
|
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");
|
debug!("Building Wiki object");
|
||||||
Ok(Some(Wiki::new(self, name)))
|
Ok(Some(Wiki::new(self, name)))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -61,7 +61,7 @@ impl<'a, 'b> Wiki<'a, 'b> {
|
||||||
.get(sid)
|
.get(sid)
|
||||||
.context("Cannot get ID from store")
|
.context("Cannot get ID from store")
|
||||||
.map_err(Error::from)?
|
.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>>> {
|
pub fn get_entry<EN: AsRef<str>>(&self, entry_name: EN) -> Result<Option<FileLockEntry<'a>>> {
|
||||||
|
|
|
@ -54,10 +54,10 @@ impl Annotateable for Entry {
|
||||||
store.retrieve(crate::module_path::new_id(ann_name.clone())?)
|
store.retrieve(crate::module_path::new_id(ann_name.clone())?)
|
||||||
.and_then(|mut anno| {
|
.and_then(|mut anno| {
|
||||||
{
|
{
|
||||||
let _ = anno.set_isflag::<IsAnnotation>()?;
|
anno.set_isflag::<IsAnnotation>()?;
|
||||||
let _ = anno
|
let _ = anno
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.insert("annotation.name", Value::String(String::from(ann_name)))?;
|
.insert("annotation.name", Value::String(ann_name))?;
|
||||||
}
|
}
|
||||||
Ok(anno)
|
Ok(anno)
|
||||||
})
|
})
|
||||||
|
@ -74,7 +74,7 @@ impl Annotateable for Entry {
|
||||||
// exist.
|
// exist.
|
||||||
fn denotate<'a>(&mut self, store: &'a Store, ann_name: &str) -> Result<Option<FileLockEntry<'a>>> {
|
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)?)? {
|
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))
|
Ok(Some(annotation))
|
||||||
} else {
|
} else {
|
||||||
// error: annotation does not exist
|
// error: annotation does not exist
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl Category for Entry {
|
||||||
.read_string(CATEGORY_REGISTER_NAME_FIELD_PATH)
|
.read_string(CATEGORY_REGISTER_NAME_FIELD_PATH)
|
||||||
.context(format_err!("Failed to read header at '{}'", CATEGORY_REGISTER_NAME_FIELD_PATH))
|
.context(format_err!("Failed to read header at '{}'", CATEGORY_REGISTER_NAME_FIELD_PATH))
|
||||||
.map_err(Error::from)?
|
.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>> {
|
fn get_entries<'a>(&self, store: &'a Store) -> Result<CategoryEntryIterator<'a>> {
|
||||||
|
|
|
@ -65,10 +65,10 @@ impl EntryCategory for Entry {
|
||||||
trace!("Setting category '{}' checked", s);
|
trace!("Setting category '{}' checked", s);
|
||||||
let mut category = register
|
let mut category = register
|
||||||
.get_category_by_name(s)?
|
.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)?;
|
self.set_category(s)?;
|
||||||
let _ = self.add_link(&mut category)?;
|
self.add_link(&mut category)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ impl EntryCategory for Entry {
|
||||||
trace!("Getting category from '{}'", self.get_location());
|
trace!("Getting category from '{}'", self.get_location());
|
||||||
self.get_header()
|
self.get_header()
|
||||||
.read_string("category.value")?
|
.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> {
|
fn has_category(&self) -> Result<bool> {
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl<'a> Iterator for CategoryEntryIterator<'a> {
|
||||||
let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
|
let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
|
||||||
let entry = self.0
|
let entry = self.0
|
||||||
.get(next)?
|
.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))
|
Ok((entry.get_category()?, entry))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ use failure::err_msg;
|
||||||
use crate::iter::CategoryNameIter;
|
use crate::iter::CategoryNameIter;
|
||||||
use crate::category::IsCategory;
|
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
|
/// 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())?
|
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)?;
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
for entry in category.get_entries(self)? {
|
for entry in category.get_entries(self)? {
|
||||||
let mut entry = entry?;
|
let mut entry = entry?;
|
||||||
let _ = category.remove_link(&mut entry)?;
|
category.remove_link(&mut entry)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ mod tests {
|
||||||
|
|
||||||
match header_field {
|
match header_field {
|
||||||
Some(ref s) => assert_eq!(category_name, s),
|
Some(ref s) => assert_eq!(category_name, s),
|
||||||
None => assert!(false, "Header field not present"),
|
None => panic!("Header field not present"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ impl DatePathCompiler {
|
||||||
|
|
||||||
pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
|
pub fn new(accuracy: Accuracy, format: Format) -> DatePathCompiler {
|
||||||
DatePathCompiler {
|
DatePathCompiler {
|
||||||
accuracy : accuracy,
|
accuracy,
|
||||||
format : format,
|
format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,10 @@ pub trait EntryDate {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DATE_HEADER_LOCATION : &'static str = "datetime.value";
|
const DATE_HEADER_LOCATION : &str = "datetime.value";
|
||||||
const DATE_RANGE_START_HEADER_LOCATION : &'static str = "datetime.range.start";
|
const DATE_RANGE_START_HEADER_LOCATION : &str = "datetime.range.start";
|
||||||
const DATE_RANGE_END_HEADER_LOCATION : &'static str = "datetime.range.end";
|
const DATE_RANGE_END_HEADER_LOCATION : &str = "datetime.range.end";
|
||||||
const DATE_FMT : &'static str = "%Y-%m-%dT%H:%M:%S";
|
const DATE_FMT : &str = "%Y-%m-%dT%H:%M:%S";
|
||||||
|
|
||||||
impl EntryDate for Entry {
|
impl EntryDate for Entry {
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ impl EntryDate for Entry {
|
||||||
/// header in an inconsistent state.
|
/// header in an inconsistent state.
|
||||||
///
|
///
|
||||||
fn delete_date_range(&mut self) -> Result<()> {
|
fn delete_date_range(&mut self) -> Result<()> {
|
||||||
let _ = self
|
self
|
||||||
.get_header_mut()
|
.get_header_mut()
|
||||||
.delete(&DATE_RANGE_START_HEADER_LOCATION)
|
.delete(&DATE_RANGE_START_HEADER_LOCATION)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
|
@ -228,6 +228,7 @@ mod tests {
|
||||||
fn test_set_date() {
|
fn test_set_date() {
|
||||||
let store = get_store();
|
let store = get_store();
|
||||||
|
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let date = {
|
let date = {
|
||||||
let date = NaiveDate::from_ymd(2000, 01, 02);
|
let date = NaiveDate::from_ymd(2000, 01, 02);
|
||||||
let time = NaiveTime::from_hms(03, 04, 05);
|
let time = NaiveTime::from_hms(03, 04, 05);
|
||||||
|
@ -255,11 +256,12 @@ mod tests {
|
||||||
|
|
||||||
match *hdr_field {
|
match *hdr_field {
|
||||||
Value::String(ref s) => assert_eq!("2000-01-02T03:04:05", s),
|
Value::String(ref s) => assert_eq!("2000-01-02T03:04:05", s),
|
||||||
_ => assert!(false, "Wrong header type"),
|
_ => panic!("Wrong header type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
fn test_read_date() {
|
fn test_read_date() {
|
||||||
use chrono::Datelike;
|
use chrono::Datelike;
|
||||||
use chrono::Timelike;
|
use chrono::Timelike;
|
||||||
|
@ -300,6 +302,7 @@ mod tests {
|
||||||
fn test_delete_date() {
|
fn test_delete_date() {
|
||||||
let store = get_store();
|
let store = get_store();
|
||||||
|
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let date = {
|
let date = {
|
||||||
let date = NaiveDate::from_ymd(2000, 01, 02);
|
let date = NaiveDate::from_ymd(2000, 01, 02);
|
||||||
let time = NaiveTime::from_hms(03, 04, 05);
|
let time = NaiveTime::from_hms(03, 04, 05);
|
||||||
|
|
|
@ -56,11 +56,13 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_returns_error_if_start_after_end_date() {
|
fn test_new_returns_error_if_start_after_end_date() {
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let start = NaiveDateTime::new(
|
let start = NaiveDateTime::new(
|
||||||
NaiveDate::from_ymd(2000, 02, 02),
|
NaiveDate::from_ymd(2000, 02, 02),
|
||||||
NaiveTime::from_hms(12, 00, 02)
|
NaiveTime::from_hms(12, 00, 02)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let end = NaiveDateTime::new(
|
let end = NaiveDateTime::new(
|
||||||
NaiveDate::from_ymd(2000, 02, 02),
|
NaiveDate::from_ymd(2000, 02, 02),
|
||||||
NaiveTime::from_hms(12, 00, 01)
|
NaiveTime::from_hms(12, 00, 01)
|
||||||
|
@ -73,11 +75,13 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_returns_ok_if_start_is_before_end() {
|
fn test_new_returns_ok_if_start_is_before_end() {
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let start = NaiveDateTime::new(
|
let start = NaiveDateTime::new(
|
||||||
NaiveDate::from_ymd(2000, 02, 02),
|
NaiveDate::from_ymd(2000, 02, 02),
|
||||||
NaiveTime::from_hms(12, 00, 01)
|
NaiveTime::from_hms(12, 00, 01)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[allow(clippy::zero_prefixed_literal)]
|
||||||
let end = NaiveDateTime::new(
|
let end = NaiveDateTime::new(
|
||||||
NaiveDate::from_ymd(2000, 02, 02),
|
NaiveDate::from_ymd(2000, 02, 02),
|
||||||
NaiveTime::from_hms(12, 00, 02)
|
NaiveTime::from_hms(12, 00, 02)
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl EditHeader for Entry {
|
||||||
|
|
||||||
fn edit_header(&mut self, rt: &Runtime) -> Result<()> {
|
fn edit_header(&mut self, rt: &Runtime) -> Result<()> {
|
||||||
let mut header = ::toml::ser::to_string_pretty(self.get_header())?;
|
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)?;
|
let header = ::toml::de::from_str(&header)?;
|
||||||
*self.get_header_mut() = header;
|
*self.get_header_mut() = header;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -65,7 +65,7 @@ impl EditHeader for Entry {
|
||||||
|
|
||||||
fn edit_header_and_content(&mut self, rt: &Runtime) -> Result<()> {
|
fn edit_header_and_content(&mut self, rt: &Runtime) -> Result<()> {
|
||||||
let mut header_and_content = self.to_str()?;
|
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)
|
self.replace_from_buffer(&header_and_content)
|
||||||
.context("Failed to replace header and content from buffer")
|
.context("Failed to replace header and content from buffer")
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
|
@ -79,7 +79,7 @@ pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> Result<()> {
|
||||||
let editor = rt
|
let editor = rt
|
||||||
.editor()
|
.editor()
|
||||||
.context(err_msg("No 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)
|
edit_in_tmpfile_with_command(editor, s)
|
||||||
.context(EM::IO)
|
.context(EM::IO)
|
||||||
|
|
|
@ -51,13 +51,13 @@ impl FailableFilter<Entry> for FieldIsEmpty {
|
||||||
.read(&self.header_field_path[..])?
|
.read(&self.header_field_path[..])?
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
match v {
|
match v {
|
||||||
&Value::Array(ref a) => a.is_empty(),
|
Value::Array(ref a) => a.is_empty(),
|
||||||
&Value::String(ref s) => s.is_empty(),
|
Value::String(ref s) => s.is_empty(),
|
||||||
&Value::Table(ref t) => t.is_empty(),
|
Value::Table(ref t) => t.is_empty(),
|
||||||
&Value::Boolean(_) |
|
Value::Boolean(_) |
|
||||||
&Value::Float(_) |
|
Value::Float(_) |
|
||||||
&Value::Datetime(_) |
|
Value::Datetime(_) |
|
||||||
&Value::Integer(_) => false,
|
Value::Integer(_) => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or(true))
|
.unwrap_or(true))
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<P: Predicate> FieldPredicate<P> {
|
||||||
pub fn new(path: FieldPath, predicate: Box<P>) -> FieldPredicate<P> {
|
pub fn new(path: FieldPath, predicate: Box<P>) -> FieldPredicate<P> {
|
||||||
FieldPredicate {
|
FieldPredicate {
|
||||||
header_field_path: path,
|
header_field_path: path,
|
||||||
predicate: predicate,
|
predicate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub struct VersionEq {
|
||||||
impl VersionEq {
|
impl VersionEq {
|
||||||
|
|
||||||
pub fn new(version: Version) -> VersionEq {
|
pub fn new(version: Version) -> VersionEq {
|
||||||
VersionEq { version: version }
|
VersionEq { version }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub struct VersionGt {
|
||||||
impl VersionGt {
|
impl VersionGt {
|
||||||
|
|
||||||
pub fn new(version: Version) -> VersionGt {
|
pub fn new(version: Version) -> VersionGt {
|
||||||
VersionGt { version: version }
|
VersionGt { version }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue