tiempo-rs/src/commands/kill.rs

79 lines
2.3 KiB
Rust

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<Args> {
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<D, I, O, E>(args: Args, streams: &mut Streams<D, I, O, E>, 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(&current_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(())
}
}