use std::convert::TryFrom; use std::io::{self, Write}; use clap::ArgMatches; use chrono::{DateTime, Utc}; use crate::error::{Error, Result}; use crate::database::Database; use crate::config::Config; use super::Command; fn read_line() -> String { let mut pre_n = String::new(); io::stdin().read_line(&mut pre_n).unwrap(); pre_n } #[derive(Debug)] pub enum Args { Id(u64), Sheet(String), } impl<'a> TryFrom<&'a ArgMatches<'a>> for Args { type Error = Error; fn try_from(args: &'a ArgMatches) -> Result { Ok(args.value_of("id").map(|v| { Args::Id(v.parse().unwrap()) }).unwrap_or_else(|| { Args::Sheet(args.value_of("sheet").unwrap().to_owned()) })) } } pub struct KillCommand; impl<'a> Command<'a> for KillCommand { type Args = Args; fn handle(args: Args, db: &mut D, out: &mut O, _err: &mut E, _config: &Config, _now: DateTime) -> Result<()> where D: Database, O: Write, E: Write, { match args { Args::Id(id) => { if let Some(entry) = db.entry_by_id(id)? { write!(out, "are you sure you want to delete entry {}? ({}) [y/n] ", entry.id, entry.note.unwrap_or_else(|| "".into()))?; io::stdout().flush()?; if read_line().to_lowercase().starts_with('y') { db.delete_entry_by_id(id)?; writeln!(out, "It's dead")?; } else { writeln!(out, "Don't worry, it's still there")?; } } else { writeln!(out, "There's no entry with id {}. Someone found it before we did.", id)?; } }, Args::Sheet(sheet) => { let n = db.entries_by_sheet(&sheet, None, None)?.len(); write!(out, "are you sure you want to delete {} entries on sheet \"{}\"? [y/n] ", n, sheet)?; io::stdout().flush()?; if read_line().to_lowercase().starts_with('y') { db.delete_entries_in_sheet(&sheet)?; writeln!(out, "They're gone")?; } else { writeln!(out, "Don't worry, they're still there")?; } } } Ok(()) } }