diff --git a/bin/core/imag-annotate/src/main.rs b/bin/core/imag-annotate/src/main.rs index cf758c4f..790ce8fb 100644 --- a/bin/core/imag-annotate/src/main.rs +++ b/bin/core/imag-annotate/src/main.rs @@ -135,7 +135,6 @@ fn remove(rt: &Runtime) { } fn list(rt: &Runtime) { - let mut out = ::std::io::stdout(); let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap let with_text = scmd.is_present("list-with-text"); match scmd.value_of("entry").map(PathBuf::from) { @@ -150,7 +149,7 @@ fn list(rt: &Runtime) { .map_err_trace_exit_unwrap(1) .enumerate() .map(|(i, a)| { - list_annotation(&mut out, i, a.map_err_trace_exit_unwrap(1), with_text) + list_annotation(&rt, i, a.map_err_trace_exit_unwrap(1), with_text) }) .collect::>(); } @@ -163,22 +162,22 @@ fn list(rt: &Runtime) { .map_err_trace_exit_unwrap(1) .enumerate() .map(|(i, a)| { - list_annotation(&mut out, i, a.map_err_trace_exit_unwrap(1), with_text) + list_annotation(&rt, i, a.map_err_trace_exit_unwrap(1), with_text) }) .collect::>(); } } } -fn list_annotation<'a>(out: &mut Write, 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 { - writeln!(out, + writeln!(rt.stdout(), "--- {i: >5} | {id}\n{text}\n\n", i = i, id = a.get_location(), text = a.get_content()) } else { - writeln!(out, "{: >5} | {}", i, a.get_location()) + writeln!(rt.stdout(), "{: >5} | {}", i, a.get_location()) } .to_exit_code() .unwrap_or_exit(); diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs index 43172192..50dd2be0 100644 --- a/bin/core/imag-diagnostics/src/main.rs +++ b/bin/core/imag-diagnostics/src/main.rs @@ -155,7 +155,7 @@ fn main() { let n = diags.len(); - let mut out = ::std::io::stdout(); + let mut out = rt.stdout(); let _ = writeln!(out, "imag version {}", env!("CARGO_PKG_VERSION")) .to_exit_code() diff --git a/bin/core/imag-gps/src/main.rs b/bin/core/imag-gps/src/main.rs index 56423286..3277547b 100644 --- a/bin/core/imag-gps/src/main.rs +++ b/bin/core/imag-gps/src/main.rs @@ -144,10 +144,8 @@ fn remove(rt: &Runtime) { }) .map_err_trace_exit_unwrap(1); // The parsing of the deleted values failed - let mut out = ::std::io::stdout(); - if scmd.is_present("print-removed") { - let _ = writeln!(out, "{}", removed_value).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}", removed_value).to_exit_code().unwrap_or_exit(); } } @@ -174,7 +172,6 @@ fn get(rt: &Runtime) { exit(1) }); - let mut out = ::std::io::stdout(); - let _ = writeln!(out, "{}", value).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}", value).to_exit_code().unwrap_or_exit(); } diff --git a/bin/core/imag-grep/src/main.rs b/bin/core/imag-grep/src/main.rs index 64220f90..1f97e4a2 100644 --- a/bin/core/imag-grep/src/main.rs +++ b/bin/core/imag-grep/src/main.rs @@ -44,6 +44,7 @@ use std::io::Write; use regex::Regex; +use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagstore::store::Entry; use libimagerror::trace::MapErrTrace; @@ -88,15 +89,13 @@ fn main() { .into_get_iter() .filter_map(|res| res.map_err_trace_exit_unwrap(1)) .filter(|entry| pattern.is_match(entry.get_content())) - .map(|entry| show(&entry, &pattern, &opts, &mut count)) + .map(|entry| show(&rt, &entry, &pattern, &opts, &mut count)) .count(); - let mut out = ::std::io::stdout(); - if opts.count { - let _ = writeln!(out, "{}", count).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}", count).to_exit_code().unwrap_or_exit(); } else if !opts.files_with_matches { - let _ = writeln!(out, "Processed {} files, {} matches, {} nonmatches", + let _ = writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches", overall_count, count, overall_count - count) @@ -105,24 +104,22 @@ fn main() { } } -fn show(e: &Entry, re: &Regex, opts: &Options, count: &mut usize) { - let mut out = ::std::io::stdout(); - +fn show(rt: &Runtime, e: &Entry, re: &Regex, opts: &Options, count: &mut usize) { if opts.files_with_matches { - let _ = writeln!(out, "{}", e.get_location()).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}", e.get_location()).to_exit_code().unwrap_or_exit(); } else if opts.count { *count += 1; } else { - let _ = writeln!(out, "{}:", e.get_location()).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}:", e.get_location()).to_exit_code().unwrap_or_exit(); for capture in re.captures_iter(e.get_content()) { for mtch in capture.iter() { if let Some(m) = mtch { - let _ = writeln!(out, " '{}'", m.as_str()).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), " '{}'", m.as_str()).to_exit_code().unwrap_or_exit(); } } } - let _ = writeln!(out, "").to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "").to_exit_code().unwrap_or_exit(); } } diff --git a/bin/core/imag-ids/src/main.rs b/bin/core/imag-ids/src/main.rs index 3b3a4638..98dd779b 100644 --- a/bin/core/imag-ids/src/main.rs +++ b/bin/core/imag-ids/src/main.rs @@ -60,13 +60,11 @@ fn main() { "print all ids", build_ui); - let mut out = ::std::io::stdout(); - rt.store() .entries() .map_err_trace_exit_unwrap(1) .for_each(|id| { - let _ = writeln!(out, "{}", id.to_str().map_err_trace_exit_unwrap(1)) + let _ = writeln!(rt.stdout(), "{}", id.to_str().map_err_trace_exit_unwrap(1)) .to_exit_code() .unwrap_or_exit(); }) diff --git a/bin/core/imag-init/src/main.rs b/bin/core/imag-init/src/main.rs index 742ad20c..356b3bca 100644 --- a/bin/core/imag-init/src/main.rs +++ b/bin/core/imag-init/src/main.rs @@ -68,7 +68,7 @@ imagrc.toml fn main() { let version = make_imag_version!(); - let app = ui::build_ui(&version); + let app = ui::build_ui(&version); let matches = app.get_matches(); let mut out = ::std::io::stdout(); diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index 271f64ab..639df976 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -254,7 +254,6 @@ fn list_linkings(rt: &Runtime) { .unwrap(); // safed by clap let list_externals = cmd.is_present("list-externals-too"); - let mut out = ::std::io::stdout(); for entry in cmd.values_of("entries").unwrap() { // safed by clap match rt.store().get(PathBuf::from(entry)) { @@ -268,7 +267,7 @@ fn list_linkings(rt: &Runtime) { .ok(); if let Some(link) = link { - let _ = writeln!(out, "{: <3}: {}", i, link) + let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link) .to_exit_code() .unwrap_or_exit(); i += 1; @@ -284,7 +283,7 @@ fn list_linkings(rt: &Runtime) { .map_err_trace_exit_unwrap(1) .into_string(); - let _ = writeln!(out, "{: <3}: {}", i, link) + let _ = writeln!(rt.stdout(), "{: <3}: {}", i, link) .to_exit_code() .unwrap_or_exit(); diff --git a/bin/core/imag-store/src/retrieve.rs b/bin/core/imag-store/src/retrieve.rs index 20dc100c..ea895138 100644 --- a/bin/core/imag-store/src/retrieve.rs +++ b/bin/core/imag-store/src/retrieve.rs @@ -51,11 +51,9 @@ pub fn retrieve(rt: &Runtime) { } pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) { - let mut out = ::std::io::stdout(); - if do_print_raw(scmd) { debug!("Printing raw content..."); - let _ = writeln!(out, "{}", e.to_str()) + let _ = writeln!(rt.stdout(), "{}", e.to_str()) .to_exit_code() .unwrap_or_exit(); } else if do_filter(scmd) { @@ -74,7 +72,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) { unimplemented!() } else { debug!("Printing header as TOML..."); - let _ = writeln!(out, "{}", e.get_header()) + let _ = writeln!(rt.stdout(), "{}", e.get_header()) .to_exit_code() .unwrap_or_exit(); } @@ -82,7 +80,7 @@ pub fn print_entry(rt: &Runtime, scmd: &ArgMatches, e: FileLockEntry) { if do_print_content(scmd) { debug!("Printing content..."); - let _ = writeln!(out, "{}", e.get_content()) + let _ = writeln!(rt.stdout(), "{}", e.get_content()) .to_exit_code() .unwrap_or_exit(); } diff --git a/bin/core/imag-tag/src/main.rs b/bin/core/imag-tag/src/main.rs index 9fb21188..ecec7afa 100644 --- a/bin/core/imag-tag/src/main.rs +++ b/bin/core/imag-tag/src/main.rs @@ -164,11 +164,9 @@ fn list(id: PathBuf, rt: &Runtime) { unimplemented!() } - let mut out = ::std::io::stdout(); - if line_out { for tag in &tags { - let _ = writeln!(out, "{}", tag) + let _ = writeln!(rt.stdout(), "{}", tag) .to_exit_code() .unwrap_or_exit(); } @@ -176,13 +174,13 @@ fn list(id: PathBuf, rt: &Runtime) { if sepp_out { let sepp = scmd.value_of("sep").unwrap(); // we checked before - let _ = writeln!(out, "{}", tags.join(sepp)) + let _ = writeln!(rt.stdout(), "{}", tags.join(sepp)) .to_exit_code() .unwrap_or_exit(); } if comm_out { - let _ = writeln!(out, "{}", tags.join(", ")) + let _ = writeln!(rt.stdout(), "{}", tags.join(", ")) .to_exit_code() .unwrap_or_exit(); } diff --git a/bin/domain/imag-bookmark/src/main.rs b/bin/domain/imag-bookmark/src/main.rs index 9fbd75e0..48f349c4 100644 --- a/bin/domain/imag-bookmark/src/main.rs +++ b/bin/domain/imag-bookmark/src/main.rs @@ -135,11 +135,10 @@ fn list(rt: &Runtime) { .map_err_trace_exit_unwrap(1); let links = collection.links(rt.store()).map_err_trace_exit_unwrap(1); - let mut out = ::std::io::stdout(); debug!("Listing..."); for (i, link) in links.enumerate() { match link { - Ok(link) => writeln!(out, "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(), + Ok(link) => writeln!(rt.stdout(), "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(), Err(e) => trace_error(&e) } }; diff --git a/bin/domain/imag-contact/src/create.rs b/bin/domain/imag-contact/src/create.rs index 9b44b703..03dde897 100644 --- a/bin/domain/imag-contact/src/create.rs +++ b/bin/domain/imag-contact/src/create.rs @@ -20,7 +20,6 @@ use std::collections::BTreeMap; use std::process::exit; use std::io::Write; -use std::io::stdout; use std::path::PathBuf; use std::fs::OpenOptions; @@ -96,7 +95,7 @@ pub fn create(rt: &Runtime) { (Box::new(file), Some(fl)) } else { - (Box::new(stdout()), None) + (Box::new(rt.stdout()), None) } }; diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs index 35ad1e0b..ba50d1b8 100644 --- a/bin/domain/imag-contact/src/main.rs +++ b/bin/domain/imag-contact/src/main.rs @@ -109,7 +109,6 @@ fn main() { fn list(rt: &Runtime) { let scmd = rt.cli().subcommand_matches("list").unwrap(); let list_format = get_contact_print_format("contact.list_format", rt, &scmd); - let mut out = ::std::io::stdout(); let _ = rt .store() @@ -144,7 +143,7 @@ fn list(rt: &Runtime) { .map_err(CE::from) .map_err_trace_exit_unwrap(1); - writeln!(out, "{}", s).to_exit_code().unwrap_or_exit() + writeln!(rt.stdout(), "{}", s).to_exit_code().unwrap_or_exit() }) .collect::>(); } diff --git a/bin/domain/imag-diary/src/list.rs b/bin/domain/imag-diary/src/list.rs index 051fb028..158ef577 100644 --- a/bin/domain/imag-diary/src/list.rs +++ b/bin/domain/imag-diary/src/list.rs @@ -33,13 +33,11 @@ pub fn list(rt: &Runtime) { let diaryname = get_diary_name(rt) .unwrap_or_else(|| warn_exit("No diary selected. Use either the configuration file or the commandline option", 1)); - let mut out = ::std::io::stdout(); - Diary::entries(rt.store(), &diaryname) .map_dbg_str("Ok") .map_err_trace_exit_unwrap(1) .for_each(|id| { - writeln!(out, "{}", id + writeln!(rt.stdout(), "{}", id .without_base() .to_str() .map_err_trace() diff --git a/bin/domain/imag-diary/src/main.rs b/bin/domain/imag-diary/src/main.rs index bbd443d2..ccaf3ab8 100644 --- a/bin/domain/imag-diary/src/main.rs +++ b/bin/domain/imag-diary/src/main.rs @@ -47,12 +47,7 @@ extern crate libimagstore; extern crate libimagtimeui; extern crate libimagutil; -use std::io::Write; -use std::process::exit; - -use libimagerror::exit::ExitUnwrap; -use libimagerror::io::ToExitCode; -use libimagrt::runtime::Runtime; +use libimagrt::setup::generate_runtime_setup; mod create; mod delete; @@ -66,25 +61,14 @@ use create::create; use delete::delete; use edit::edit; use list::list; -use ui::build_ui; use view::view; fn main() { let version = make_imag_version!(); - let name = "imag-diary"; - let about = "Personal Diary/Diaries"; - let ui = build_ui(Runtime::get_default_cli_builder(name, &version, about)); - let rt = { - let rt = Runtime::new(ui); - if rt.is_ok() { - rt.unwrap() - } else { - let mut out = ::std::io::stdout(); - let _ = writeln!(out, "Could not set up Runtime").to_exit_code().unwrap_or_exit(); - let _ = writeln!(out, "{:?}", rt.err().unwrap()).to_exit_code().unwrap_or_exit(); - exit(1); - } - }; + let rt = generate_runtime_setup("imag-diary", + &version, + "Personal Diary/Diaries", + ui::build_ui); rt.cli() .subcommand_name() diff --git a/bin/domain/imag-habit/src/main.rs b/bin/domain/imag-habit/src/main.rs index 8594dfbe..0a7288b6 100644 --- a/bin/domain/imag-habit/src/main.rs +++ b/bin/domain/imag-habit/src/main.rs @@ -332,8 +332,7 @@ fn today(rt: &Runtime, future: bool) { } if !empty { - let mut out = ::std::io::stdout(); - let _ = table.print(&mut out).to_exit_code().unwrap_or_exit(); + let _ = table.print(&mut rt.stdout()).to_exit_code().unwrap_or_exit(); } } } @@ -388,8 +387,7 @@ fn list(rt: &Runtime) { }); if !empty { - let mut out = ::std::io::stdout(); - let _ = table.print(&mut out).to_exit_code().unwrap_or_exit(); + let _ = table.print(&mut rt.stdout()).to_exit_code().unwrap_or_exit(); } } @@ -411,7 +409,6 @@ fn show(rt: &Runtime) { vec![date, comm] } - let mut out = ::std::io::stdout(); let header = ["#", "Date", "Comment"] .iter() .map(|s| Cell::new(s)) @@ -433,7 +430,7 @@ fn show(rt: &Runtime) { let recur = habit.habit_recur_spec().map_err_trace_exit_unwrap(1); let comm = habit.habit_comment().map_err_trace_exit_unwrap(1); - let _ = writeln!(out, + let _ = writeln!(rt.stdout(), "{i} - {name}\nBase : {b},\nRecurrence: {r}\nComment : {c}\n", i = i, name = name, @@ -461,8 +458,7 @@ fn show(rt: &Runtime) { }); if !empty { - let mut out = ::std::io::stdout(); - let _ = table.print(&mut out).to_exit_code().unwrap_or_exit(); + let _ = table.print(&mut rt.stdout()).to_exit_code().unwrap_or_exit(); } }) .collect::>(); diff --git a/bin/domain/imag-log/src/main.rs b/bin/domain/imag-log/src/main.rs index 9c0f199d..7c2804ec 100644 --- a/bin/domain/imag-log/src/main.rs +++ b/bin/domain/imag-log/src/main.rs @@ -137,7 +137,7 @@ fn show(rt: &Runtime) { } let id = e.diary_id().map_err_trace_exit_unwrap(1); - writeln!(::std::io::stdout(), + writeln!(rt.stdout(), "{dname: >10} - {y: >4}-{m:0>2}-{d:0>2}T{H:0>2}:{M:0>2} - {text}", dname = id.diary_name(), y = id.year(), diff --git a/bin/domain/imag-mail/src/main.rs b/bin/domain/imag-mail/src/main.rs index b822aeba..a108d692 100644 --- a/bin/domain/imag-mail/src/main.rs +++ b/bin/domain/imag-mail/src/main.rs @@ -73,7 +73,7 @@ fn list(rt: &Runtime) { use libimagmail::error::ResultExt; // TODO: Implement lister type in libimagmail for this - fn list_mail(m: Mail) { + fn list_mail(rt: &Runtime, m: Mail) { let id = match m.get_message_id() { Ok(Some(f)) => f, Ok(None) => "".to_owned(), @@ -110,7 +110,7 @@ fn list(rt: &Runtime) { }, }; - writeln!(::std::io::stdout(), + writeln!(rt.stdout(), "Mail: {id}\n\tFrom: {from}\n\tTo: {to}\n\t{subj}\n", from = from, id = id, @@ -130,7 +130,7 @@ fn list(rt: &Runtime) { .map(|fle| Mail::from_fle(fle).map_err_trace().ok()) }) .filter_map(|e| e) - .for_each(list_mail); + .for_each(|m| list_mail(&rt, m)); } fn mail_store(rt: &Runtime) { diff --git a/bin/domain/imag-notes/src/main.rs b/bin/domain/imag-notes/src/main.rs index df1870e2..de395c54 100644 --- a/bin/domain/imag-notes/src/main.rs +++ b/bin/domain/imag-notes/src/main.rs @@ -119,8 +119,6 @@ fn edit(rt: &Runtime) { fn list(rt: &Runtime) { use std::cmp::Ordering; - let mut out = ::std::io::stdout(); - let _ = rt .store() .all_notes() @@ -139,7 +137,7 @@ fn list(rt: &Runtime) { .iter() .for_each(|note| { let name = note.get_name().map_err_trace_exit_unwrap(1); - writeln!(out, "{}", name) + writeln!(rt.stdout(), "{}", name) .to_exit_code() .unwrap_or_exit() }); diff --git a/bin/domain/imag-timetrack/src/day.rs b/bin/domain/imag-timetrack/src/day.rs index 4bdbcda6..97451920 100644 --- a/bin/domain/imag-timetrack/src/day.rs +++ b/bin/domain/imag-timetrack/src/day.rs @@ -86,7 +86,6 @@ pub fn day(rt: &Runtime) -> i32 { tags_filter.and(start_time_filter).and(end_time_filter) }; - let mut out = ::std::io::stdout(); rt.store() .get_timetrackings() .map_err_trace_exit_unwrap(1) @@ -111,9 +110,9 @@ pub fn day(rt: &Runtime) -> i32 { .trace_unwrap_exit(1) .map(|(tag, start, end)| { match (start, end) { - (None, _) => writeln!(out, "{} has no start time.", tag), - (Some(s), None) => writeln!(out, "{} | {} - ...", tag, s), - (Some(s), Some(e)) => writeln!(out, "{} | {} - {}", tag, s, e), + (None, _) => writeln!(rt.stdout(), "{} has no start time.", tag), + (Some(s), None) => writeln!(rt.stdout(), "{} | {} - ...", tag, s), + (Some(s), Some(e)) => writeln!(rt.stdout(), "{} | {} - {}", tag, s, e), } .to_exit_code() }) diff --git a/bin/domain/imag-timetrack/src/list.rs b/bin/domain/imag-timetrack/src/list.rs index 2ecf7580..f79493d4 100644 --- a/bin/domain/imag-timetrack/src/list.rs +++ b/bin/domain/imag-timetrack/src/list.rs @@ -117,8 +117,6 @@ pub fn list_impl(rt: &Runtime, let mut table = Table::new(); table.set_titles(Row::new(["Tag", "Start", "End"].into_iter().map(|s| Cell::new(s)).collect())); - let mut stdout = ::std::io::stdout(); - rt.store() .get_timetrackings() .map_err_trace_exit_unwrap(1) @@ -167,7 +165,7 @@ pub fn list_impl(rt: &Runtime, }) }) .map_err_trace_exit_unwrap(1) - .print(&mut stdout) + .print(&mut rt.stdout()) .map_err(|_| TimeTrackError::from(String::from("Failed printing table"))) .map(|_| 0) .map_err_trace() diff --git a/bin/domain/imag-timetrack/src/month.rs b/bin/domain/imag-timetrack/src/month.rs index 90c38619..13414e7a 100644 --- a/bin/domain/imag-timetrack/src/month.rs +++ b/bin/domain/imag-timetrack/src/month.rs @@ -101,8 +101,6 @@ pub fn month(rt: &Runtime) -> i32 { tags_filter.and(start_time_filter).and(end_time_filter) }; - let mut out = ::std::io::stdout(); - rt.store() .get_timetrackings() .map_err_trace_exit_unwrap(1) @@ -127,9 +125,9 @@ pub fn month(rt: &Runtime) -> i32 { .trace_unwrap_exit(1) .map(|(tag, start, end)| { match (start, end) { - (None, _) => writeln!(out, "{} has no start time.", tag), - (Some(s), None) => writeln!(out, "{} | {} - ...", tag, s), - (Some(s), Some(e)) => writeln!(out, "{} | {} - {}", tag, s, e), + (None, _) => writeln!(rt.stdout(), "{} has no start time.", tag), + (Some(s), None) => writeln!(rt.stdout(), "{} | {} - ...", tag, s), + (Some(s), Some(e)) => writeln!(rt.stdout(), "{} | {} - {}", tag, s, e), } .to_exit_code() }) diff --git a/bin/domain/imag-timetrack/src/week.rs b/bin/domain/imag-timetrack/src/week.rs index a73657d8..db1cec90 100644 --- a/bin/domain/imag-timetrack/src/week.rs +++ b/bin/domain/imag-timetrack/src/week.rs @@ -99,7 +99,6 @@ pub fn week(rt: &Runtime) -> i32 { tags_filter.and(start_time_filter).and(end_time_filter) }; - let mut out = ::std::io::stdout(); rt.store() .get_timetrackings() .map_err_trace_exit_unwrap(1) @@ -124,9 +123,9 @@ pub fn week(rt: &Runtime) -> i32 { .trace_unwrap_exit(1) .map(|(tag, start, end)| { match (start, end) { - (None, _) => writeln!(out, "{} has no start time.", tag), - (Some(s), None) => writeln!(out, "{} | {} - ...", tag, s), - (Some(s), Some(e)) => writeln!(out, "{} | {} - {}", tag, s, e), + (None, _) => writeln!(rt.stdout(), "{} has no start time.", tag), + (Some(s), None) => writeln!(rt.stdout(), "{} | {} - ...", tag, s), + (Some(s), Some(e)) => writeln!(rt.stdout(), "{} | {} - {}", tag, s, e), } .to_exit_code() }) diff --git a/bin/domain/imag-timetrack/src/year.rs b/bin/domain/imag-timetrack/src/year.rs index cddd21a1..4db59ec2 100644 --- a/bin/domain/imag-timetrack/src/year.rs +++ b/bin/domain/imag-timetrack/src/year.rs @@ -98,7 +98,7 @@ pub fn year(rt: &Runtime) -> i32 { tags_filter.and(start_time_filter).and(end_time_filter) }; - let mut out = ::std::io::stdout(); + let mut out = rt.stdout(); rt.store() .get_timetrackings() .map_err_trace_exit_unwrap(1) diff --git a/bin/domain/imag-todo/src/main.rs b/bin/domain/imag-todo/src/main.rs index 8fab4e46..7eaf1d80 100644 --- a/bin/domain/imag-todo/src/main.rs +++ b/bin/domain/imag-todo/src/main.rs @@ -71,7 +71,7 @@ fn tw_hook(rt: &Runtime) { .import_task_from_reader(stdin) .map_err_trace_exit_unwrap(1); - let _ = writeln!(::std::io::stdout(), "{}\nTask {} stored in imag", line, uuid) + let _ = writeln!(rt.stdout(), "{}\nTask {} stored in imag", line, uuid) .to_exit_code() .unwrap_or_exit(); @@ -148,7 +148,7 @@ fn list(rt: &Runtime) { }; // and then print that - let _ = writeln!(::std::io::stdout(), "{}", outstring).to_exit_code().unwrap_or_exit(); + let _ = writeln!(rt.stdout(), "{}", outstring).to_exit_code().unwrap_or_exit(); }); res.map_err_trace().ok(); diff --git a/lib/core/libimagrt/Cargo.toml b/lib/core/libimagrt/Cargo.toml index e8a569ba..11e38d5f 100644 --- a/lib/core/libimagrt/Cargo.toml +++ b/lib/core/libimagrt/Cargo.toml @@ -29,6 +29,7 @@ is-match = "0.1" toml-query = "0.6" error-chain = "0.11" handlebars = "0.29.0" +atty = "0.2" libimagstore = { version = "0.7.0", path = "../../../lib/core/libimagstore" } libimagerror = { version = "0.7.0", path = "../../../lib/core/libimagerror" } diff --git a/lib/core/libimagrt/src/io.rs b/lib/core/libimagrt/src/io.rs new file mode 100644 index 00000000..5f6bc9d8 --- /dev/null +++ b/lib/core/libimagrt/src/io.rs @@ -0,0 +1,66 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 Matthias Beyer and contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +//! Proxy objects for std::io::Stdin, std::io::Stdout, std::io::Stderr + +use std::fmt::Debug; +use std::io::Write; + +/// Proxy object for output +/// +/// This is returned by `Runtime::stdout()` does implement `Write`. So you can +/// `write!(rt.stdout(), "some things")` and it just works. +/// +/// The `Runtime` has to decide whether the OutputProxy should write to stdout, stderr or simply be +/// a "sink" which does not write to either. +/// +pub enum OutputProxy { + Out, + Err, + Sink, +} + +impl Write for OutputProxy { + fn write(&mut self, buf: &[u8]) -> ::std::io::Result { + match *self { + OutputProxy::Out => ::std::io::stdout().write(buf), + OutputProxy::Err => ::std::io::stderr().write(buf), + OutputProxy::Sink => Ok(0), + } + } + + fn flush(&mut self) -> ::std::io::Result<()> { + match *self { + OutputProxy::Out => ::std::io::stdout().flush(), + OutputProxy::Err => ::std::io::stderr().flush(), + OutputProxy::Sink => Ok(()), + } + } + +} + +impl Debug for OutputProxy { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + match *self { + OutputProxy::Out => write!(f, "OutputProxy(Stdout)"), + OutputProxy::Err => write!(f, "OutputProxy(Stderr)"), + OutputProxy::Sink => write!(f, "OutputProxy(Sink)"), + } + } +} diff --git a/lib/core/libimagrt/src/lib.rs b/lib/core/libimagrt/src/lib.rs index b6c6e735..d56d638c 100644 --- a/lib/core/libimagrt/src/lib.rs +++ b/lib/core/libimagrt/src/lib.rs @@ -47,6 +47,7 @@ extern crate clap; extern crate toml; extern crate toml_query; #[macro_use] extern crate is_match; +extern crate atty; extern crate libimagstore; extern crate libimagutil; @@ -56,6 +57,7 @@ extern crate libimaginteraction; pub mod error; pub mod configuration; pub mod logger; +pub mod io; pub mod runtime; pub mod setup; pub mod spec; diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs index e1f8fa8a..e76618c7 100644 --- a/lib/core/libimagrt/src/runtime.rs +++ b/lib/core/libimagrt/src/runtime.rs @@ -21,6 +21,7 @@ use std::path::PathBuf; use std::process::Command; use std::env; use std::process::exit; +use std::io::Stdin; pub use clap::App; use toml::Value; @@ -32,6 +33,7 @@ use error::RuntimeError; use error::RuntimeErrorKind; use error::ResultExt; use logger::ImagLogger; +use io::OutputProxy; use libimagerror::trace::*; use libimagstore::store::Store; @@ -47,6 +49,8 @@ pub struct Runtime<'a> { configuration: Option, cli_matches: ArgMatches<'a>, store: Store, + stdin_is_tty: bool, + stdout_is_tty: bool, } impl<'a> Runtime<'a> { @@ -150,6 +154,8 @@ impl<'a> Runtime<'a> { configuration: config, rtp: rtp, store: store, + stdout_is_tty: ::atty::is(::atty::Stream::Stdout), + stdin_is_tty: ::atty::is(::atty::Stream::Stdin), } }) .chain_err(|| RuntimeErrorKind::Instantiate) @@ -438,6 +444,26 @@ impl<'a> Runtime<'a> { .or(env::var("EDITOR").ok()) .map(Command::new) } + + pub fn stdout(&self) -> OutputProxy { + if self.stdout_is_tty { + OutputProxy::Out + } else { + OutputProxy::Err + } + } + + pub fn stderr(&self) -> OutputProxy { + OutputProxy::Err + } + + pub fn stdin(&self) -> Option { + if self.stdin_is_tty { + Some(::std::io::stdin()) + } else { + None + } + } } /// Exported for the `imag` command, you probably do not want to use that.