use std::convert::TryFrom; use std::io::{BufRead, Write}; use clap::ArgMatches; use crate::error::{Error, Result}; use crate::database::Database; use crate::interactive::{ask, confirm_deletion}; use crate::io::Streams; use super::{Command, Facts}; #[derive(Debug)] pub enum Args { Id(u64), Sheet(String), Last, } impl<'a> TryFrom<&'a ArgMatches> for Args { type Error = Error; fn try_from(args: &'a ArgMatches) -> Result { Ok(if let Some(id) = args.value_of("id") { Args::Id(id.parse().unwrap()) } else if args.is_present("last") { Args::Last } else if let Some(sheet) = args.value_of("sheet") { Args::Sheet(sheet.to_owned()) } else { unreachable!() }) } } pub struct KillCommand; impl<'a> Command<'a> for KillCommand { type Args = Args; fn handle(args: Args, streams: &mut Streams, facts: &Facts) -> Result<()> where D: Database, I: BufRead, O: Write, E: Write, { match args { Args::Id(id) => { if let Some(entry) = streams.db.entry_by_id(id)? { confirm_deletion(streams, entry, facts.now)?; } else { writeln!(streams.out, "There's no entry with id {}. Someone found it before we did.", id)?; } } Args::Last => { let current_sheet = streams.db.current_sheet()?; if let Some(entry) = streams.db.last_entry_of_sheet(¤t_sheet)? { confirm_deletion(streams, entry, facts.now)?; } else { writeln!(streams.out, "Nothing to delete")?; } } Args::Sheet(sheet) => { let n = streams.db.entries_by_sheet(&sheet, None, None)?.len(); if ask(streams, &format!("are you sure you want to delete {} entries on sheet \"{}\"?", n, sheet))? { streams.db.delete_entries_in_sheet(&sheet)?; writeln!(streams.out, "They're gone")?; } else { writeln!(streams.out, "Don't worry, they're still there")?; } } } Ok(()) } }