2021-08-02 18:45:54 -05:00
use std ::convert ::TryFrom ;
2021-08-25 14:30:27 -05:00
use std ::io ::{ BufRead , Write } ;
2021-08-02 18:45:54 -05:00
use clap ::ArgMatches ;
use crate ::error ::{ Result , Error } ;
use crate ::database ::Database ;
use crate ::old ::{ entries_or_warning , warn_if_needed } ;
use crate ::tabulate ::{ Tabulate , Col , Align ::* } ;
use crate ::formatters ::text ::format_duration ;
2021-08-25 14:30:27 -05:00
use crate ::io ::Streams ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
use super ::{ Command , Facts } ;
2021-08-02 18:45:54 -05:00
#[ derive(Default) ]
pub struct Args {
}
2023-02-13 18:17:47 -06:00
impl < ' a > TryFrom < & ' a ArgMatches > for Args {
2021-08-02 18:45:54 -05:00
type Error = Error ;
fn try_from ( _matches : & ' a ArgMatches ) -> Result < Args > {
Ok ( Args { } )
}
}
pub struct NowCommand { }
impl < ' a > Command < ' a > for NowCommand {
type Args = Args ;
2021-08-25 14:30:27 -05:00
fn handle < D , I , O , E > ( _args : Self ::Args , streams : & mut Streams < D , I , O , E > , facts : & Facts ) -> Result < ( ) >
2021-08-02 18:45:54 -05:00
where
D : Database ,
2021-08-25 14:30:27 -05:00
I : BufRead ,
2021-08-02 18:45:54 -05:00
O : Write ,
E : Write ,
{
2021-08-25 14:30:27 -05:00
let entries = streams . db . running_entries ( ) ? ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
let ( entries , needs_warning ) = entries_or_warning ( entries , & streams . db ) ? ;
2021-08-02 18:45:54 -05:00
2022-11-09 14:19:11 -06:00
if entries . is_empty ( ) {
streams . out . write_all ( b " No running entries \n " ) ? ;
} else {
let current = streams . db . current_sheet ( ) ? ;
let last = streams . db . last_sheet ( ) ? ;
let mut tabs = Tabulate ::with_columns ( vec! [
// indicator of current or prev sheet
Col ::new ( ) . min_width ( 1 ) . and_alignment ( Right ) ,
// sheet name
Col ::new ( ) . min_width ( 9 ) . and_alignment ( Left ) ,
// running time
Col ::new ( ) . min_width ( 9 ) . and_alignment ( Right ) ,
// activity
Col ::new ( ) . min_width ( 0 ) . and_alignment ( Left ) ,
2021-08-02 18:45:54 -05:00
] ) ;
2022-11-09 14:19:11 -06:00
tabs . feed ( vec! [ " " , " Timesheet " , " Running " , " Activity " ] ) ;
tabs . separator ( ' ' ) ;
for entry in entries {
tabs . feed ( vec! [
if current = = entry . sheet {
" * "
} else if last . as_ref ( ) = = Some ( & entry . sheet ) {
" - "
} else {
" "
} . to_string ( ) ,
entry . sheet ,
format_duration ( facts . now - entry . start ) ,
entry . note . unwrap_or_default ( ) ,
] ) ;
}
streams . out . write_all ( tabs . print ( facts . env . stdout_is_tty ) . as_bytes ( ) ) ? ;
}
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
warn_if_needed ( & mut streams . err , needs_warning , & facts . env ) ? ;
2021-08-02 18:45:54 -05:00
Ok ( ( ) )
}
}
#[ cfg(test) ]
mod tests {
use chrono ::{ Utc , TimeZone , Local } ;
2022-11-09 14:19:11 -06:00
use pretty_assertions ::assert_str_eq ;
2021-08-02 18:45:54 -05:00
use crate ::database ::{ SqliteDatabase , Database } ;
use super ::* ;
#[ test ]
fn list_sheets ( ) {
2021-08-11 17:54:37 -05:00
std ::env ::set_var ( " TZ " , " CST+6 " ) ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
let mut streams = Streams ::fake ( b " " ) ;
2023-02-13 18:17:47 -06:00
let now = Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 13 , 52 , 45 ) . unwrap ( ) ;
2021-08-25 14:30:27 -05:00
let facts = Facts ::new ( ) . with_now ( now ) ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
streams . db . set_current_sheet ( " sheet2 " ) . unwrap ( ) ;
streams . db . set_last_sheet ( " sheet4 " ) . unwrap ( ) ;
2021-08-02 18:45:54 -05:00
2023-02-13 18:17:47 -06:00
streams . db . entry_insert ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 0 , 0 , 0 ) . unwrap ( ) , Some ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 1 , 0 , 0 ) . unwrap ( ) ) , None , " _archived " ) . unwrap ( ) ;
streams . db . entry_insert ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 0 , 0 , 0 ) . unwrap ( ) , Some ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 10 , 13 , 55 ) . unwrap ( ) ) , None , " sheet1 " ) . unwrap ( ) ;
streams . db . entry_insert ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 0 , 0 , 0 ) . unwrap ( ) , Some ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 7 , 39 , 18 ) . unwrap ( ) ) , None , " sheet3 " ) . unwrap ( ) ;
streams . db . entry_insert ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 12 , 0 , 0 ) . unwrap ( ) , Some ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 13 , 52 , 45 ) . unwrap ( ) ) , None , " sheet3 " ) . unwrap ( ) ;
streams . db . entry_insert ( Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 12 , 0 , 0 ) . unwrap ( ) , None , Some ( " some " . to_string ( ) ) , " sheet4 " ) . unwrap ( ) ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
NowCommand ::handle ( Default ::default ( ) , & mut streams , & facts ) . unwrap ( ) ;
2021-08-02 18:45:54 -05:00
2022-11-09 14:19:11 -06:00
assert_str_eq! ( & String ::from_utf8_lossy ( & streams . out ) , " Timesheet Running Activity
2021-08-02 18:45:54 -05:00
- sheet4 1 :52 :45 some
2022-07-19 05:38:37 -05:00
" );
2021-08-02 18:45:54 -05:00
}
#[ test ]
fn old_database ( ) {
2021-08-25 14:30:27 -05:00
let mut streams = Streams ::fake ( b " " ) . with_db (
SqliteDatabase ::from_path ( " assets/test_list_old_database.db " ) . unwrap ( )
) ;
2021-08-02 18:45:54 -05:00
2023-02-13 18:17:47 -06:00
let now = Local . with_ymd_and_hms ( 2021 , 7 , 16 , 11 , 30 , 45 ) . unwrap ( ) ;
2021-08-25 14:30:27 -05:00
let facts = Facts ::new ( ) . with_now ( now . with_timezone ( & Utc ) ) ;
2021-08-02 18:45:54 -05:00
2021-08-25 14:30:27 -05:00
NowCommand ::handle ( Default ::default ( ) , & mut streams , & facts ) . unwrap ( ) ;
2021-08-02 18:45:54 -05:00
2022-11-09 14:19:11 -06:00
assert_str_eq! ( & String ::from_utf8_lossy ( & streams . out ) , " Timesheet Running Activity
2021-08-02 18:45:54 -05:00
* default 0 :10 :24 que
2022-07-19 05:38:37 -05:00
" );
2021-08-02 18:45:54 -05:00
2022-11-09 14:19:11 -06:00
assert_str_eq! (
2021-08-25 14:30:27 -05:00
String ::from_utf8_lossy ( & streams . err ) ,
2022-08-29 18:03:11 -05:00
" [WARNING] You are using the old timetrap format, it is advised that you update your database using t migrate. To supress this warning set TIEMPO_SUPRESS_TIMETRAP_WARNING=1 \n "
2021-08-02 18:45:54 -05:00
) ;
}
2022-11-09 14:19:11 -06:00
#[ test ]
fn with_no_running_entries_display_nicer_message ( ) {
std ::env ::set_var ( " TZ " , " CST+6 " ) ;
let mut streams = Streams ::fake ( b " " ) ;
2023-02-13 18:17:47 -06:00
let now = Utc . with_ymd_and_hms ( 2021 , 1 , 1 , 13 , 52 , 45 ) . unwrap ( ) ;
2022-11-09 14:19:11 -06:00
let facts = Facts ::new ( ) . with_now ( now ) ;
NowCommand ::handle ( Default ::default ( ) , & mut streams , & facts ) . unwrap ( ) ;
assert_str_eq! ( & String ::from_utf8_lossy ( & streams . out ) , " No running entries
" );
}
2021-08-02 18:45:54 -05:00
}