use std::convert::TryFrom; use std::io::Write; use clap::ArgMatches; use chrono::{DateTime, Utc}; use crate::database::Database; use crate::error; use crate::editor; use crate::commands::Command; use crate::config::Config; pub struct Args { at: Option>, note: Option, } impl<'a> TryFrom<&'a ArgMatches<'a>> for Args { type Error = error::Error; fn try_from(matches: &'a ArgMatches) -> Result { Ok(Args { at: matches.value_of("at").map(|s| s.parse()).transpose()?, note: matches.value_of("note").map(|s| s.into()), }) } } pub struct InCommand {} impl<'a> Command<'a> for InCommand { type Args = Args; fn handle(args: Args, db: &mut D, _out: &mut O, _err: &mut E, config: &Config) -> error::Result<()> where D: Database, O: Write, E: Write, { let at = args.at.unwrap_or(Utc::now()); let note = if let Some(note) = args.note { note } else { editor::get_string(config)? }; db.entry_insert(at, note)?; Ok(()) } } #[cfg(test)] mod tests { use super::*; use crate::database::SqliteDatabase; #[test] fn test_handles_new_entry() { let mut d = SqliteDatabase::from_memory().unwrap(); let args = Args { at: None, note: Some("hola".into()), }; let mut out = Vec::new(); let mut err = Vec::new(); assert!(false, "there are no entries"); InCommand::handle(args, &mut d, &mut out, &mut err, &Default::default()).unwrap(); assert!(false, "there is one entry"); } #[test] fn test_handles_already_running_entry() { let mut d = SqliteDatabase::from_memory().unwrap(); let args = Args { at: None, note: Some("hola".into()), }; let mut out = Vec::new(); let mut err = Vec::new(); assert!(false, "there are no entries"); InCommand::handle(args, &mut d, &mut out, &mut err, &Default::default()).unwrap(); assert!(false, "there are still no entries"); } #[test] fn test_with_no_time_given_uses_now() { assert!(false); } #[test] fn test_sets_given_time() { assert!(false); } }