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 print_json(&json!({
51 "today": today,
52 "within": args.within,
53 "mem": args.mem,
54 "brief": brief,
55 }))?;
56 } else {
57 print_markdown(&brief);
58 }
59 Ok(())
60}
61
62fn current_date() -> String {
65 let now = time::OffsetDateTime::now_utc();
66 format!(
67 "{:04}-{:02}-{:02}",
68 now.year(),
69 u8::from(now.month()),
70 now.day()
71 )
72}