Skip to main content

things3_cloud/commands/
mod.rs

1pub mod anytime;
2pub mod area;
3pub mod areas;
4pub mod completions;
5pub mod delete;
6pub mod edit;
7pub mod find;
8pub mod inbox;
9pub mod logbook;
10pub mod mark;
11pub mod new;
12pub mod project;
13pub mod projects;
14pub mod reorder;
15pub mod schedule;
16pub mod set_auth;
17pub mod someday;
18pub mod tags;
19pub mod today;
20pub mod upcoming;
21pub mod webserver;
22
23use anyhow::Result;
24use clap::{Args, Subcommand};
25use serde::Serialize;
26
27use crate::{
28    app::Cli,
29    cmd_ctx::{CmdCtx, DefaultCmdCtx},
30};
31
32pub trait Command {
33    fn run_with_ctx(
34        &self,
35        cli: &Cli,
36        out: &mut dyn std::io::Write,
37        ctx: &mut dyn CmdCtx,
38    ) -> Result<()>;
39
40    fn run(&self, cli: &Cli, out: &mut dyn std::io::Write) -> Result<()> {
41        let mut ctx = DefaultCmdCtx::from_cli(cli);
42        self.run_with_ctx(cli, out, &mut ctx)
43    }
44}
45
46pub(crate) fn detailed_json_conflict(json: bool, detailed: bool) -> bool {
47    if json && detailed {
48        eprintln!("--detailed is not supported with --json.");
49        true
50    } else {
51        false
52    }
53}
54
55pub(crate) fn write_json<T: Serialize>(out: &mut dyn std::io::Write, value: &T) -> Result<()> {
56    serde_json::to_writer_pretty(&mut *out, value)?;
57    writeln!(out)?;
58    Ok(())
59}
60
61#[derive(Debug, Default, Clone, Args)]
62pub struct DetailedArgs {
63    /// Show notes beneath each task
64    #[arg(long, short = 'd')]
65    pub detailed: bool,
66}
67
68#[derive(Debug, Default, Clone, Args)]
69pub struct TagDeltaArgs {
70    #[arg(
71        long = "add-tags",
72        short = 'a',
73        help = "Comma-separated tags to add (titles or UUID prefixes)"
74    )]
75    pub add_tags: Option<String>,
76    #[arg(
77        long = "remove-tags",
78        short = 'r',
79        help = "Comma-separated tags to remove (titles or UUID prefixes)"
80    )]
81    pub remove_tags: Option<String>,
82}
83
84#[derive(Debug, Subcommand)]
85pub enum Commands {
86    #[command(about = "Show the Inbox")]
87    Inbox(inbox::InboxArgs),
88    #[command(about = "Show the Today view (default)")]
89    Today(today::TodayArgs),
90    #[command(about = "Show tasks scheduled for the future")]
91    Upcoming(upcoming::UpcomingArgs),
92    #[command(about = "Show the Anytime view")]
93    Anytime(anytime::AnytimeArgs),
94    #[command(about = "Show the Someday view")]
95    Someday(someday::SomedayArgs),
96    #[command(about = "Show the Logbook")]
97    Logbook(logbook::LogbookArgs),
98    #[command(about = "Show, create, or edit projects")]
99    Projects(projects::ProjectsArgs),
100    #[command(about = "Show all tasks in a project")]
101    Project(project::ProjectArgs),
102    #[command(about = "Show or create areas")]
103    Areas(areas::AreasArgs),
104    #[command(about = "Show projects and tasks in an area")]
105    Area(area::AreaArgs),
106    #[command(about = "Show or edit tags")]
107    Tags(tags::TagsArgs),
108    #[command(about = "Create a new task")]
109    New(new::NewArgs),
110    #[command(about = "Edit a task title, container, notes, tags, or checklist items")]
111    Edit(edit::EditArgs),
112    #[command(about = "Mark a task done, incomplete, or canceled")]
113    Mark(mark::MarkArgs),
114    #[command(about = "Set when and deadline")]
115    Schedule(schedule::ScheduleArgs),
116    #[command(about = "Reorder item relative to another item")]
117    Reorder(reorder::ReorderArgs),
118    #[command(about = "Delete tasks/projects/headings/areas")]
119    Delete(delete::DeleteArgs),
120    #[command(about = "Configure Things Cloud credentials")]
121    SetAuth(set_auth::SetAuthArgs),
122    #[command(about = "Search and filter tasks")]
123    Find(find::FindArgs),
124    #[command(hide = true, about = "Generate shell completion scripts")]
125    Completions(completions::CompletionsArgs),
126    #[command(hide = true, about = "Run internal HTTP bridge server")]
127    Webserver(webserver::WebserverArgs),
128}
129
130impl Command for Commands {
131    fn run_with_ctx(
132        &self,
133        cli: &Cli,
134        out: &mut dyn std::io::Write,
135        ctx: &mut dyn CmdCtx,
136    ) -> Result<()> {
137        match self {
138            Commands::Inbox(args) => args.run_with_ctx(cli, out, ctx),
139            Commands::Today(args) => args.run_with_ctx(cli, out, ctx),
140            Commands::Upcoming(args) => args.run_with_ctx(cli, out, ctx),
141            Commands::Anytime(args) => args.run_with_ctx(cli, out, ctx),
142            Commands::Someday(args) => args.run_with_ctx(cli, out, ctx),
143            Commands::Logbook(args) => args.run_with_ctx(cli, out, ctx),
144            Commands::Projects(args) => args.run_with_ctx(cli, out, ctx),
145            Commands::Project(args) => args.run_with_ctx(cli, out, ctx),
146            Commands::Areas(args) => args.run_with_ctx(cli, out, ctx),
147            Commands::Area(args) => args.run_with_ctx(cli, out, ctx),
148            Commands::Tags(args) => args.run_with_ctx(cli, out, ctx),
149            Commands::New(args) => args.run_with_ctx(cli, out, ctx),
150            Commands::Edit(args) => args.run_with_ctx(cli, out, ctx),
151            Commands::Mark(args) => args.run_with_ctx(cli, out, ctx),
152            Commands::Schedule(args) => args.run_with_ctx(cli, out, ctx),
153            Commands::Reorder(args) => args.run_with_ctx(cli, out, ctx),
154            Commands::Delete(args) => args.run_with_ctx(cli, out, ctx),
155            Commands::SetAuth(args) => args.run_with_ctx(cli, out, ctx),
156            Commands::Find(args) => args.run_with_ctx(cli, out, ctx),
157            Commands::Completions(args) => args.run_with_ctx(cli, out, ctx),
158            Commands::Webserver(args) => args.run_with_ctx(cli, out, ctx),
159        }
160    }
161}