diff options
Diffstat (limited to 'bin/domain/imag-timetrack/src/list.rs')
-rw-r--r-- | bin/domain/imag-timetrack/src/list.rs | 233 |
1 files changed, 100 insertions, 133 deletions
diff --git a/bin/domain/imag-timetrack/src/list.rs b/bin/domain/imag-timetrack/src/list.rs index c323cf29..b44f7ed0 100644 --- a/bin/domain/imag-timetrack/src/list.rs +++ b/bin/domain/imag-timetrack/src/list.rs @@ -18,7 +18,6 @@ // use chrono::NaiveDateTime; -use filters::filter::Filter; use prettytable::Table; use prettytable::Row; use prettytable::Cell; @@ -27,60 +26,44 @@ use kairos::parser::parse as kairos_parse; use clap::ArgMatches; use failure::Fallible as Result; use failure::ResultExt; -use failure::err_msg; use failure::Error; +use resiter::Filter; +use resiter::AndThen; +use resiter::Map; -use libimagerror::trace::trace_error; -use libimagerror::trace::MapErrTrace; -use libimagerror::iter::TraceIterator; -use libimagerror::exit::ExitUnwrap; use libimagstore::store::FileLockEntry; -use libimagtimetrack::store::TimeTrackStore; use libimagtimetrack::timetracking::TimeTracking; +use libimagtimetrack::store::TimeTrackStore; use libimagrt::runtime::Runtime; -pub fn list(rt: &Runtime) -> i32 { +pub fn list(rt: &Runtime) -> Result<()> { let (_, cmd) = rt.cli().subcommand(); let cmd = cmd.unwrap(); // checked in main() let gettime = |cmd: &ArgMatches, name| { match cmd.value_of(name).map(kairos_parse) { - Some(Ok(Parsed::TimeType(tt))) => match tt.calculate() { - Ok(tt) => { - let dt = tt.get_moment().unwrap_or_else(|| { - error!("Failed to get date from '{}'", cmd.value_of(name).unwrap()); - ::std::process::exit(1) - }); - - Some(*dt) - }, - Err(e) => { - error!("Failed to calculate date from '{}': {:?}", - cmd.value_of(name).unwrap(), e); - ::std::process::exit(1) - }, + Some(Ok(Parsed::TimeType(tt))) => { + let tt = tt + .calculate() + .context(format_err!("Failed to calculate date from '{}'", cmd.value_of(name).unwrap()))?; + Ok(tt.get_moment().cloned()) }, Some(Ok(Parsed::Iterator(_))) => { - error!("Expected single point in time, got '{}', which yields a list of dates", cmd.value_of(name).unwrap()); - ::std::process::exit(1) + Err(format_err!("Expected single point in time, got '{}', which yields a list of dates", cmd.value_of(name).unwrap())) }, - Some(Err(e)) => { - let e = e; - trace_error(&e); - ::std::process::exit(1) - } - None => None, + Some(Err(e)) => Err(e), + None => Ok(None), } }; - let start = gettime(&cmd, "start-time"); - let end = gettime(&cmd, "end-time"); + let start = gettime(&cmd, "start-time")?; + let end = gettime(&cmd, "end-time")?; let list_not_ended = cmd.is_present("list-not-ended"); let show_duration = cmd.is_present("show-duration"); - list_impl(rt, start, end, list_not_ended, show_duration) + list_impl(rt, start.clone(), end.clone(), list_not_ended, show_duration) } pub fn list_impl(rt: &Runtime, @@ -88,34 +71,27 @@ pub fn list_impl(rt: &Runtime, end: Option<NaiveDateTime>, list_not_ended: bool, show_duration: bool) - -> i32 + -> Result<()> { + use filters::failable::filter::FailableFilter; - let start_time_filter = |timetracking: &FileLockEntry| { - start.map(|s| match timetracking.get_start_datetime() { - Ok(Some(dt)) => dt >= s, - Ok(None) => { + let start_time_filter = |timetracking: &FileLockEntry| -> Result<bool> { + start.map(|s| match timetracking.get_start_datetime()? { + Some(dt) => Ok(dt >= s), + None => { warn!("Funny things are happening: Timetracking has no start time"); - false - } - Err(e) => { - trace_error(&e); - false + Ok(false) } }) - .unwrap_or(true) + .unwrap_or(Ok(true)) }; - let end_time_filter = |timetracking: &FileLockEntry| { - end.map(|s| match timetracking.get_end_datetime() { - Ok(Some(dt)) => dt <= s, - Ok(None) => list_not_ended, - Err(e) => { - trace_error(&e); - false - } + let end_time_filter = |timetracking: &FileLockEntry| -> Result<bool> { + end.map(|s| match timetracking.get_end_datetime()? { + Some(dt) => Ok(dt <= s), + None => Ok(list_not_ended), }) - .unwrap_or(true) + .unwrap_or(Ok(true)) }; let filter = start_time_filter.and(end_time_filter); @@ -128,92 +104,83 @@ pub fn list_impl(rt: &Runtime, }; table.set_titles(title_row); - let mut table_empty = true; - - let table = rt.store() - .get_timetrackings() - .map_err_trace_exit_unwrap() - .trace_unwrap() - .filter(|e| filter.filter(e)) - .fold(Ok(table), |acc: Result<_>, e| { - acc.and_then(|mut tab: Table| { - debug!("Processing {:?}", e.get_location()); - - let tag = e.get_timetrack_tag()?; - debug!(" -> tag = {:?}", tag); - - let start = e.get_start_datetime()?; - debug!(" -> start = {:?}", start); - - let end = e.get_end_datetime()?; - debug!(" -> end = {:?}", end); - - let v = match (start, end) { - (None, _) => { - let mut v = vec![String::from(tag.as_str()), String::from(""), String::from("")]; - if show_duration { - v.push(String::from("")); - } - v - }, - (Some(s), None) => { - let mut v = vec![ - String::from(tag.as_str()), - format!("{}", s), - String::from(""), - ]; - - if show_duration { - v.push(String::from("")); - } - - v - }, - (Some(s), Some(e)) => { - let mut v = vec![ - String::from(tag.as_str()), - format!("{}", s), - format!("{}", e), - ]; - - if show_duration { - let duration = e - s; - let dur = format!("{days} Days, {hours} Hours, {minutes} Minutes, {seconds} Seconds", - days = duration.num_days(), - hours = duration.num_hours(), - minutes = duration.num_minutes(), - seconds = duration.num_seconds()); - - v.push(dur); - } - - v - }, - }; - - let cells : Vec<Cell> = v - .into_iter() - .map(|s| Cell::new(&s)) - .collect(); - tab.add_row(Row::new(cells)); - - rt.report_touched(e.get_location()).unwrap_or_exit(); - - table_empty = false; - Ok(tab) - }) + let table_empty = rt.store() + .get_timetrackings()? + .and_then_ok(|e| filter.filter(&e).map(|b| (b, e))) + .filter_ok(|tpl| tpl.0) + .map_ok(|tpl| tpl.1) + .and_then_ok(|e| { + debug!("Processing {:?}", e.get_location()); + + let tag = e.get_timetrack_tag()?; + debug!(" -> tag = {:?}", tag); + + let start = e.get_start_datetime()?; + debug!(" -> start = {:?}", start); + + let end = e.get_end_datetime()?; + debug!(" -> end = {:?}", end); + + let v = match (start, end) { + (None, _) => { + let mut v = vec![String::from(tag.as_str()), String::from(""), String::from("")]; + if show_duration { + v.push(String::from("")); + } + v + }, + (Some(s), None) => { + let mut v = vec![ + String::from(tag.as_str()), + format!("{}", s), + String::from(""), + ]; + + if show_duration { + v.push(String::from("")); + } + + v + }, + (Some(s), Some(e)) => { + let mut v = vec![ + String::from(tag.as_str()), + format!("{}", s), + format!("{}", e), + ]; + + if show_duration { + let duration = e - s; + let dur = format!("{days} Days, {hours} Hours, {minutes} Minutes, {seconds} Seconds", + days = duration.num_days(), + hours = duration.num_hours(), + minutes = duration.num_minutes(), + seconds = duration.num_seconds()); + + v.push(dur); + } + + v + }, + }; + + let cells : Vec<Cell> = v.iter().map(|s| Cell::new(s)).collect(); + table.add_row(Row::new(cells)); + + rt.report_touched(e.get_location())?; + Ok(false) }) - .map_err_trace_exit_unwrap(); + .collect::<Result<Vec<bool>>>()? + .iter() + .any(|b| !b); if !table_empty { table.print(&mut rt.stdout()) - .context(err_msg("Failed to print table")) + .context("Failed to print table") .map_err(Error::from) - .map(|_| 0) - .map_err_trace() - .unwrap_or(1) + .map(|_| ()) } else { - 0 + Ok(()) } } |