use std::path::PathBuf;
use crate::{
config::Config,
labels, projects, sections,
tasks::{add, close, comment, create, edit, list, view},
};
use clap::{Args, Parser, Subcommand};
use color_eyre::Result;
#[derive(Parser, Debug)]
#[command(author, version, about)]
pub struct Arguments {
#[arg(long = "config_prefix")]
config_prefix: Option<PathBuf>,
#[command(subcommand)]
command: Option<Commands>,
#[command(flatten)]
params: list::Params,
}
#[derive(Subcommand, Debug)]
enum Commands {
Auth {
token: String,
},
#[command(flatten)]
Authenticated(AuthCommands),
}
#[derive(Subcommand, Debug)]
enum AuthCommands {
#[command(visible_alias = "a")]
Add(add::Params),
#[command(visible_alias = "A")]
Create(create::Params),
#[command(visible_alias = "l")]
List(list::Params),
#[command(visible_alias = "e")]
Edit(edit::Params),
#[command(visible_alias = "c")]
Close(close::Params),
#[command(visible_alias = "v")]
View(view::Params),
#[command(visible_alias = "C")]
Comment(comment::Params),
#[command(visible_alias = "p")]
Projects(ProjectArgs),
#[command(visible_alias = "lbl")]
Labels(LabelArgs),
}
#[derive(Args, Debug)]
#[command(args_conflicts_with_subcommands = true)]
struct ProjectArgs {
#[command(subcommand)]
command: Option<ProjectCommands>,
#[command(flatten)]
params: projects::list::Params,
}
#[derive(Subcommand, Debug)]
enum ProjectCommands {
#[command(visible_alias = "l")]
List(projects::list::Params),
#[command(visible_alias = "v")]
View(projects::view::Params),
#[command(visible_alias = "C")]
Comment(projects::comment::Params),
#[command(visible_alias = "a")]
Add(projects::add::Params),
#[command(visible_alias = "d")]
Delete(projects::delete::Params),
#[command(visible_alias = "s")]
Sections(SectionArgs),
}
#[derive(Args, Debug)]
#[command(args_conflicts_with_subcommands = true)]
struct LabelArgs {
#[command(subcommand)]
command: Option<LabelCommands>,
#[command(flatten)]
params: labels::list::Params,
}
#[derive(Subcommand, Debug)]
enum LabelCommands {
#[command(visible_alias = "l")]
List(labels::list::Params),
#[command(visible_alias = "a")]
Add(labels::add::Params),
#[command(visible_alias = "d")]
Delete(labels::delete::Params),
}
#[derive(Args, Debug)]
#[command(args_conflicts_with_subcommands = true)]
struct SectionArgs {
#[command(subcommand)]
command: Option<SectionCommands>,
#[command(flatten)]
params: sections::list::Params,
}
#[derive(Subcommand, Debug)]
enum SectionCommands {
#[command(visible_alias = "l")]
List(sections::list::Params),
#[command(visible_alias = "a")]
Add(sections::add::Params),
#[command(visible_alias = "d")]
Delete(sections::delete::Params),
}
impl Arguments {
pub async fn exec(self) -> Result<()> {
let mut cfg = match self.config_prefix {
Some(p) => Config::load_prefix(&p),
None => Config::load(),
}?;
match self.command {
Some(command) => match command {
Commands::Auth { token } => {
cfg.token = Some(token);
cfg.save()?;
println!("Token successfully saved")
}
Commands::Authenticated(command) => {
let gw = cfg.gateway()?;
match command {
AuthCommands::Add(p) => add::add(p, &gw, &cfg).await?,
AuthCommands::Create(p) => create::create(p, &gw, &cfg).await?,
AuthCommands::List(p) => list::list(p, &gw, &cfg).await?,
AuthCommands::Edit(p) => edit::edit(p, &gw, &cfg).await?,
AuthCommands::Close(p) => close::close(p, &gw, &cfg).await?,
AuthCommands::View(p) => view::view(p, &gw, &cfg).await?,
AuthCommands::Comment(p) => comment::comment(p, &gw, &cfg).await?,
AuthCommands::Projects(p) => match p.command {
Some(p) => match p {
ProjectCommands::List(p) => projects::list::list(p, &gw).await?,
ProjectCommands::View(p) => projects::view::view(p, &gw).await?,
ProjectCommands::Comment(p) => {
projects::comment::comment(p, &gw).await?
}
ProjectCommands::Add(p) => projects::add::add(p, &gw).await?,
ProjectCommands::Delete(p) => {
projects::delete::delete(p, &gw).await?
}
ProjectCommands::Sections(s) => match s.command {
Some(s) => match s {
SectionCommands::List(p) => {
sections::list::list(p, &gw).await?
}
SectionCommands::Add(p) => {
sections::add::add(p, &gw).await?
}
SectionCommands::Delete(p) => {
sections::delete::delete(p, &gw).await?
}
},
None => sections::list::list(s.params, &gw).await?,
},
},
None => projects::list::list(p.params, &gw).await?,
},
AuthCommands::Labels(p) => match p.command {
Some(p) => match p {
LabelCommands::List(p) => labels::list::list(p, &gw).await?,
LabelCommands::Add(p) => labels::add::add(p, &gw).await?,
LabelCommands::Delete(p) => labels::delete::delete(p, &gw).await?,
},
None => labels::list::list(p.params, &gw).await?,
},
}
}
},
None => {
list::list(self.params, &cfg.gateway()?, &cfg).await?;
}
}
Ok(())
}
}
#[cfg(test)]
mod test {
use crate::Arguments;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Arguments::command().debug_assert()
}
}