things3_cloud/commands/
upcoming.rs1use std::{io::Write, sync::Arc};
2
3use anyhow::Result;
4use clap::Args;
5use iocraft::prelude::*;
6
7use crate::{
8 app::Cli,
9 commands::{Command, DetailedArgs, detailed_json_conflict, write_json},
10 ui::{
11 render_element_to_string,
12 views::{json::common::build_tasks_json, upcoming::UpcomingView},
13 },
14 wire::task::TaskStatus,
15};
16
17#[derive(Debug, Default, Args)]
18pub struct UpcomingArgs {
19 #[command(flatten)]
20 pub detailed: DetailedArgs,
21}
22
23impl Command for UpcomingArgs {
24 fn run_with_ctx(
25 &self,
26 cli: &Cli,
27 out: &mut dyn Write,
28 ctx: &mut dyn crate::cmd_ctx::CmdCtx,
29 ) -> Result<()> {
30 let store = Arc::new(cli.load_store()?);
31 let today = ctx.today();
32 let now_ts = today.timestamp();
33
34 let mut tasks = Vec::new();
35 for t in store.tasks(Some(TaskStatus::Incomplete), Some(false), None) {
36 if t.in_someday() {
37 continue;
38 }
39 let Some(start_date) = t.start_date else {
40 continue;
41 };
42 if start_date.timestamp() > now_ts {
43 tasks.push(t);
44 }
45 }
46 tasks.sort_by_key(|t| t.start_date);
47
48 let json = cli.json;
49 if json {
50 if detailed_json_conflict(json, self.detailed.detailed) {
51 return Ok(());
52 }
53 write_json(out, &build_tasks_json(&tasks, &store, &today))?;
54 return Ok(());
55 }
56
57 let mut ui = element! {
58 ContextProvider(value: Context::owned(store.clone())) {
59 ContextProvider(value: Context::owned(today)) {
60 UpcomingView(
61 items: &tasks,
62 detailed: self.detailed.detailed,
63 )
64 }
65 }
66 };
67
68 let rendered = render_element_to_string(&mut ui, cli.no_color);
69 writeln!(out, "{}", rendered)?;
70 Ok(())
71 }
72}