use std::convert::TryFrom; use std::io::Write; use std::str::FromStr; use clap::ArgMatches; use chrono::{DateTime, Utc, Local, TimeZone}; use crate::error; use crate::database::Database; use crate::formatters::Formatter; use crate::config::Config; use super::Command; enum Sheet { All, Full, Sheet(String), } impl FromStr for Sheet { type Err = error::Error; fn from_str(name: &str) -> error::Result { Ok(match name { "all" => Sheet::All, "full" => Sheet::Full, name => Sheet::Sheet(name.into()), }) } } pub struct Args { ids: bool, start: Option>, end: Option>, format: Formatter, grep: Option, sheet: Option, } impl<'a> TryFrom<&'a ArgMatches<'a>> for Args { type Error = error::Error; fn try_from(matches: &'a ArgMatches) -> error::Result { Ok(Args { ids: matches.is_present("ids"), start: matches.value_of("at").map(|s| s.parse()).transpose()?, end: matches.value_of("at").map(|s| s.parse()).transpose()?, format: matches.value_of("format").unwrap().parse()?, grep: matches.value_of("grep").map(|s| s.into()), sheet: matches.value_of("sheet").map(|s| s.parse()).transpose()?, }) } } pub struct DisplayCommand { } impl<'a> Command<'a> for DisplayCommand { type Args = Args; fn handle(args: Self::Args, db: &mut D, out: &mut W, config: &Config) -> error::Result<()> where D: Database, W: Write, { let sheets_to_display = match args.sheet { Some(Sheet::All) => db.entries_all_visible()?, Some(Sheet::Full) => db.entries_full()?, Some(Sheet::Sheet(name)) => db.entries_by_sheet(&name)?, None => { let current_sheet = db.current_sheet()?.unwrap_or("default".into()); db.entries_by_sheet(¤t_sheet)? } }; args.format.print_formatted(sheets_to_display, out, Utc::now(), Local.offset_from_utc_datetime(&Utc::now().naive_utc()), args.ids) } }