2021-07-01 23:44:38 -05:00
use std ::convert ::TryFrom ;
use std ::io ::Write ;
use clap ::ArgMatches ;
2021-07-16 12:45:27 -05:00
use chrono ::{ DateTime , Utc } ;
2021-07-01 23:44:38 -05:00
use crate ::database ::Database ;
2021-07-14 12:37:08 -05:00
use crate ::error ::{ Error , Result } ;
2021-07-01 23:44:38 -05:00
use crate ::commands ::Command ;
use crate ::config ::Config ;
2021-07-15 16:36:24 -05:00
use crate ::commands ::list ::ListCommand ;
2021-07-01 23:44:38 -05:00
#[ derive(Default) ]
pub struct Args {
sheet : Option < String > ,
}
impl < ' a > TryFrom < & ' a ArgMatches < ' a > > for Args {
2021-07-14 12:37:08 -05:00
type Error = Error ;
2021-07-01 23:44:38 -05:00
2021-07-14 12:37:08 -05:00
fn try_from ( matches : & ' a ArgMatches ) -> Result < Self > {
2021-07-01 23:44:38 -05:00
Ok ( Args {
sheet : matches . value_of ( " sheet " ) . map ( | s | s . into ( ) ) ,
} )
}
}
pub struct SheetCommand { }
impl < ' a > Command < ' a > for SheetCommand {
type Args = Args ;
2021-07-16 12:45:27 -05:00
fn handle < D , O , E > ( args : Args , db : & mut D , out : & mut O , err : & mut E , config : & Config , now : DateTime < Utc > ) -> Result < ( ) >
2021-07-01 23:44:38 -05:00
where
D : Database ,
O : Write ,
E : Write ,
{
2021-07-23 20:37:21 -05:00
if let Some ( sheet ) = args . sheet {
let current_sheet = db . current_sheet ( ) ? . unwrap_or ( " default " . into ( ) ) ;
2021-07-14 12:37:08 -05:00
// sheet given, switch to it
2021-07-23 20:37:21 -05:00
if sheet = = " - " {
if let Some ( move_to ) = db . last_sheet ( ) ? {
db . set_last_sheet ( & current_sheet ) ? ;
db . set_current_sheet ( & move_to ) ? ;
writeln! ( out , " Switching to sheet '{}' " , move_to ) ? ;
Ok ( ( ) )
} else {
writeln! ( out , " No previous sheet to move to. Staying on '{}'. \n Hint: remember that giving - (a dash) as argument to t sheet switches to the last active sheet " , current_sheet ) ? ;
Ok ( ( ) )
}
} else {
if sheet = = current_sheet {
writeln! ( out , " Already on sheet '{}' " , sheet ) ? ;
} else {
db . set_last_sheet ( & current_sheet ) ? ;
db . set_current_sheet ( & sheet ) ? ;
writeln! ( out , " Switching to sheet '{}' " , sheet ) ? ;
}
Ok ( ( ) )
}
2021-07-14 12:37:08 -05:00
} else {
// call list
2021-07-16 12:45:27 -05:00
ListCommand ::handle ( Default ::default ( ) , db , out , err , config , now )
2021-07-14 12:37:08 -05:00
}
2021-07-01 23:44:38 -05:00
}
}
#[ cfg(test) ]
mod tests {
2021-07-23 20:37:21 -05:00
use pretty_assertions ::assert_eq ;
use crate ::database ::SqliteDatabase ;
use crate ::test_utils ::PrettyString ;
use super ::* ;
2021-07-01 23:44:38 -05:00
#[ test ]
fn switch_to_sheet ( ) {
2021-07-23 20:37:21 -05:00
let args = Args {
sheet : Some ( " new_sheet " . into ( ) ) ,
} ;
let mut db = SqliteDatabase ::from_memory ( ) . unwrap ( ) ;
let mut out = Vec ::new ( ) ;
let mut err = Vec ::new ( ) ;
let now = Utc ::now ( ) ;
db . init ( ) . unwrap ( ) ;
SheetCommand ::handle ( args , & mut db , & mut out , & mut err , & Default ::default ( ) , now ) . unwrap ( ) ;
assert_eq! ( db . current_sheet ( ) . unwrap ( ) . unwrap ( ) , " new_sheet " ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & out ) ) , PrettyString ( " Switching to sheet 'new_sheet' \n " ) ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & err ) ) , PrettyString ( " " ) ) ;
2021-07-01 23:44:38 -05:00
}
#[ test ]
fn switch_to_sheet_already_in ( ) {
2021-07-23 20:37:21 -05:00
let args = Args {
sheet : Some ( " foo " . into ( ) ) ,
} ;
let mut db = SqliteDatabase ::from_memory ( ) . unwrap ( ) ;
let mut out = Vec ::new ( ) ;
let mut err = Vec ::new ( ) ;
let now = Utc ::now ( ) ;
db . init ( ) . unwrap ( ) ;
db . set_current_sheet ( " foo " ) . unwrap ( ) ;
SheetCommand ::handle ( args , & mut db , & mut out , & mut err , & Default ::default ( ) , now ) . unwrap ( ) ;
assert_eq! ( db . current_sheet ( ) . unwrap ( ) . unwrap ( ) , " foo " ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & out ) ) , PrettyString ( " Already on sheet 'foo' \n " ) ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & err ) ) , PrettyString ( " " ) ) ;
}
#[ test ]
fn switch_to_last_sheet ( ) {
let args = Args {
sheet : Some ( " - " . into ( ) ) ,
} ;
let mut db = SqliteDatabase ::from_memory ( ) . unwrap ( ) ;
let mut out = Vec ::new ( ) ;
let mut err = Vec ::new ( ) ;
let now = Utc ::now ( ) ;
db . init ( ) . unwrap ( ) ;
db . set_current_sheet ( " foo " ) . unwrap ( ) ;
db . set_last_sheet ( " var " ) . unwrap ( ) ;
SheetCommand ::handle ( args , & mut db , & mut out , & mut err , & Default ::default ( ) , now ) . unwrap ( ) ;
assert_eq! ( db . current_sheet ( ) . unwrap ( ) . unwrap ( ) , " var " ) ;
assert_eq! ( db . last_sheet ( ) . unwrap ( ) . unwrap ( ) , " foo " ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & out ) ) , PrettyString ( " Switching to sheet 'var' \n " ) ) ;
assert_eq! ( PrettyString ( & String ::from_utf8_lossy ( & err ) ) , PrettyString ( " " ) ) ;
2021-07-01 23:44:38 -05:00
}
}