tiempo-rs/src/commands/archive.rs

86 lines
2.6 KiB
Rust

use std::convert::TryFrom;
use std::io::{BufRead, Write};
use clap::ArgMatches;
use chrono::{DateTime, Utc};
use regex::Regex;
use crate::database::Database;
use crate::error::{Error, Result};
use crate::commands::{Command, Facts};
use crate::timeparse::parse_time;
use crate::old::{entries_or_warning, time_or_warning};
use crate::formatters::text;
use crate::regex::parse_regex;
use crate::interactive::ask;
use crate::io::Streams;
#[derive(Default)]
pub struct Args {
start: Option<DateTime<Utc>>,
end: Option<DateTime<Utc>>,
grep: Option<Regex>,
fake: bool,
sheet: Option<String>,
}
impl<'a> TryFrom<&'a ArgMatches<'a>> for Args {
type Error = Error;
fn try_from(matches: &'a ArgMatches) -> Result<Self> {
Ok(Args {
start: matches.value_of("start").map(parse_time).transpose()?,
end: matches.value_of("end").map(parse_time).transpose()?,
grep: matches.value_of("grep").map(parse_regex).transpose()?,
fake: matches.is_present("fake"),
sheet: matches.value_of("sheet").map(|s| s.to_owned()),
})
}
}
pub struct ArchiveCommand {}
impl<'a> Command<'a> for ArchiveCommand {
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,
{
let mut entries = {
let start = args.start.map(|s| time_or_warning(s, &streams.db)).transpose()?.map(|s| s.0);
let end = args.end.map(|e| time_or_warning(e, &streams.db)).transpose()?.map(|e| e.0);
let current_sheet = streams.db.current_sheet()?.unwrap_or_else(|| "default".into());
let sheet = args.sheet.unwrap_or(current_sheet);
streams.db.entries_by_sheet(&sheet, start, end)?
};
if let Some(re) = args.grep {
entries.retain(|e| re.is_match(&e.note.clone().unwrap_or_else(String::new)));
}
if args.fake {
let (entries, _) = entries_or_warning(entries, &streams.db)?;
text::print_formatted(
entries,
&mut streams.out,
facts,
true,
)?;
} else if ask(streams, &format!("Archive {} entries?", entries.len()))? {
for entry in entries {
streams.db.entry_update(entry.id, entry.start, entry.end, entry.note, &format!("_{}", entry.sheet))?;
}
} else {
writeln!(streams.out, "Ok, they're still there")?;
}
Ok(())
}
}