memstead_cli/commands/
due.rs1use clap::Args as ClapArgs;
12use serde_json::json;
13
14use crate::CliError;
15use crate::output::{ExitKind, print_json, print_markdown};
16use crate::setup::CliContext;
17
18#[derive(ClapArgs, Debug)]
19pub struct Args {
20 #[arg(long, default_value = memstead_base::engine::due::DEFAULT_DUE_WINDOW)]
24 pub within: String,
25
26 #[arg(long)]
29 pub mem: Option<String>,
30
31 #[arg(long, hide = true)]
34 pub today: Option<String>,
35}
36
37pub fn run(ctx: &CliContext, args: Args) -> anyhow::Result<()> {
38 let window = memstead_base::engine::due::parse_due_window(&args.within)
39 .map_err(|msg| CliError::new(ExitKind::Validation, "INVALID_INPUT", msg))?;
40 let today = match &args.today {
41 Some(t) => t.clone(),
42 None => current_date(),
43 };
44 let engine = ctx.cli_engine()?;
45 let brief = engine
46 .base()
47 .render_due_brief(&today, &window, args.mem.as_deref())
48 .map_err(|msg| CliError::new(ExitKind::Validation, "INVALID_INPUT", msg))?;
49 if ctx.json {
50 let data = engine
53 .base()
54 .due_brief(&today, &window, args.mem.as_deref())
55 .map_err(|msg| CliError::new(ExitKind::Validation, "INVALID_INPUT", msg))?;
56 print_json(&json!({
57 "today": today,
58 "within": args.within,
59 "through": data.through,
60 "mem": args.mem,
61 "mems": data.mems,
62 "overdue": data.overdue,
63 "due_soon": data.due_soon,
64 "brief": brief,
65 }))?;
66 } else {
67 print_markdown(&brief);
68 }
69 Ok(())
70}
71
72fn current_date() -> String {
75 let now = time::OffsetDateTime::now_utc();
76 format!(
77 "{:04}-{:02}-{:02}",
78 now.year(),
79 u8::from(now.month()),
80 now.day()
81 )
82}