use std::path::PathBuf;
use clap::{Args, Parser, Subcommand};
#[derive(Args, Debug, Default)]
pub struct FilterArgs {
#[arg(long)]
pub dir: Option<String>,
#[arg(short, long)]
pub status: Option<String>,
#[arg(short, long)]
pub tag: Option<String>,
#[arg(short, long)]
pub priority: Option<String>,
#[arg(long)]
pub due_before: Option<String>,
#[arg(long)]
pub due_after: Option<String>,
}
impl FilterArgs {
pub fn is_empty(&self) -> bool {
self.dir.is_none()
&& self.status.is_none()
&& self.tag.is_none()
&& self.priority.is_none()
&& self.due_before.is_none()
&& self.due_after.is_none()
}
}
#[derive(Parser)]
#[command(name = "tasks", version, about = "Markdown-based TODO task management CLI")]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand)]
pub enum Command {
Repl,
Info,
Lib {
#[command(subcommand)]
command: LibCommand,
},
#[command(alias = "add")]
New {
title: String,
#[arg(short = 'D', long)]
description: Option<String>,
#[arg(short, long)]
priority: Option<String>,
#[arg(short, long = "tag")]
tags: Vec<String>,
#[arg(short, long)]
due: Option<String>,
#[arg(long)]
dir: Option<String>,
#[arg(long)]
template: Option<String>,
},
Template {
#[command(subcommand)]
command: TemplateCommand,
},
List {
#[command(flatten)]
filter: FilterArgs,
#[arg(short, long)]
quiet: bool,
},
Batch {
new_status: String,
#[command(flatten)]
filter: FilterArgs,
#[arg(long)]
dry_run: bool,
#[arg(short, long)]
force: bool,
},
Archive {
#[command(flatten)]
filter: FilterArgs,
#[arg(long)]
dry_run: bool,
#[arg(short, long)]
force: bool,
},
Adopt {
paths: Vec<String>,
#[arg(long)]
all: bool,
#[arg(long)]
dry_run: bool,
#[arg(long)]
rename: bool,
},
Search {
query: String,
#[arg(short, long)]
status: Option<String>,
#[arg(short, long)]
tag: Option<String>,
},
Tag {
#[command(subcommand)]
command: TagCommand,
},
Show { id: String },
Delete {
id: String,
#[arg(short, long)]
force: bool,
},
Start { id: String },
Done { id: String },
Cancel { id: String },
Status { id: String, status: String },
Set {
id: String,
#[arg(long)]
title: Option<String>,
#[arg(short = 'D', long)]
description: Option<String>,
#[arg(long)]
priority: Option<String>,
#[arg(long)]
due: Option<String>,
#[arg(long = "tag-add")]
tag_add: Vec<String>,
#[arg(long = "tag-remove")]
tag_remove: Vec<String>,
},
Step {
#[command(subcommand)]
command: StepCommand,
},
Body {
#[command(subcommand)]
command: BodyCommand,
},
Board {
#[arg(long)]
dir: Option<String>,
#[arg(short, long)]
tag: Option<String>,
#[arg(long)]
columns: Option<String>,
},
Remind {
#[arg(long)]
within: Option<String>,
#[arg(long)]
overdue: bool,
#[arg(long)]
summary: bool,
},
Overdue,
Stats,
Completions { shell: String },
FixNames {
#[arg(long)]
dry_run: bool,
},
Edit {
id: Option<String>,
#[arg(long)]
editor: Option<String>,
#[arg(long = "lib")]
lib: bool,
},
}
#[derive(Subcommand)]
pub enum TemplateCommand {
List,
Show { name: String },
New {
name: String,
#[arg(long)]
lib: bool,
#[arg(long)]
editor: Option<String>,
},
Edit {
name: String,
#[arg(long)]
editor: Option<String>,
},
Remove { name: String },
}
#[derive(Subcommand)]
pub enum BodyCommand {
Append {
id: String,
text: Vec<String>,
#[arg(long)]
after: Option<String>,
#[arg(long)]
stdin: bool,
#[arg(short, long)]
quiet: bool,
},
Replace {
id: String,
old: String,
new: Vec<String>,
#[arg(long)]
stdin: bool,
#[arg(short, long)]
quiet: bool,
},
Delete {
id: String,
prefix: String,
#[arg(short, long)]
quiet: bool,
},
}
#[derive(Subcommand)]
pub enum StepCommand {
#[command(alias = "list")]
Get { id: String },
Add { id: String, title: String },
Done { id: String, step: String },
Remove { id: String, step: String },
}
#[derive(Subcommand)]
pub enum TagCommand {
Add {
id: String,
#[arg(required = true)]
tags: Vec<String>,
},
Remove {
id: String,
#[arg(required = true)]
tags: Vec<String>,
},
List,
}
#[derive(Subcommand)]
pub enum LibCommand {
Add { name: String, path: PathBuf },
List,
Use { name: String },
Current,
Remove { name: String },
}