use boat_lib::repository::Id;
use clap::ColorChoice;
use clap::Parser;
use clap::{ArgAction, Args, Subcommand, ValueEnum};
use serde::Deserialize;
use serde::Serialize;
use crate::cli::PeriodInput;
#[derive(Parser, Debug)]
#[command(
name = "boat",
version,
author = "Made by @coko7 <contact@coko7.fr>",
color = ColorChoice::Auto,
about = "Basic Opinionated Activity Tracker",
help_template = "{name} {version}\n\n{about}\n\n{usage-heading}\n{usage}\n\n{all-args}\n\n{author}"
)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
#[command(flatten)]
pub verbose: clap_verbosity_flag::Verbosity,
}
#[derive(Subcommand, Debug)]
#[command(rename_all = "kebab-case")]
pub enum Commands {
#[command(alias = "n", alias = "create")]
New(CreateActivityArgs),
#[command(
alias = "s",
alias = "st",
alias = "sail",
alias = "continue",
alias = "resume"
)]
Start(StartActivityArgs),
#[command(alias = "c", alias = "can")]
Cancel(CancelActivityArgs),
#[command(alias = "p", alias = "stop")]
Pause,
#[command(alias = "m", alias = "mod")]
Modify(ModifyActivityArgs),
#[command(alias = "e", alias = "ed")]
Edit(EditLogsArgs),
#[command(
alias = "d",
alias = "del",
alias = "rm",
alias = "rem",
alias = "remove"
)]
Delete(DeleteActivityArgs),
#[command(alias = "g")]
Get(PrintActivityArgs),
#[command(alias = "l", alias = "ls")]
List(FilterActivitiesArgs),
#[command(alias = "r", alias = "rep")]
Report(FilterActivitiesArgs),
#[command(alias = "i")]
Init,
#[command(alias = "h", hide = true)]
HelpExtension,
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, ValueEnum, Default, PartialEq, Eq)]
pub enum GroupBy {
#[value(name = "none", alias = "no")]
#[default]
#[serde(rename = "none")]
None,
#[value(name = "day", alias = "d")]
#[serde(rename = "day")]
Day,
#[value(name = "week", alias = "wk", alias = "w")]
#[serde(rename = "week")]
Week,
#[value(name = "month", alias = "mo", alias = "m")]
#[serde(rename = "month")]
Month,
#[value(name = "year", alias = "y")]
#[serde(rename = "year")]
Year,
}
impl std::fmt::Display for GroupBy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
GroupBy::None => "none",
GroupBy::Day => "day",
GroupBy::Week => "week",
GroupBy::Month => "month",
GroupBy::Year => "year",
};
write!(f, "{str}")
}
}
#[derive(Debug, Clone, Copy, ValueEnum, Default)]
pub enum SortBy {
#[value(name = "none", alias = "no")]
#[default]
None,
}
#[derive(Args, Debug)]
pub struct FilterActivitiesArgs {
#[arg(short = 'p', long = "period")]
pub period: Option<PeriodInput>,
#[arg(short = 'g', long = "group-by")]
pub group_by: Option<GroupBy>,
#[arg(short = 't', long = "filter-by-tags", value_name = "TAGS", value_delimiter = ',', action = ArgAction::Append)]
pub filter_by_tags: Option<Vec<String>>,
#[arg(short = 'f', long = "fields", value_name = "FIELDS", value_delimiter = ',', action = ArgAction::Append)]
pub fields: Option<Vec<String>>,
#[arg(short = 'j', long = "json")]
pub use_json_format: bool,
}
#[derive(Args, Debug, Default)]
#[group(multiple = false)]
pub struct PrintActivityArgs {
#[arg(short = 'j', long = "json")]
pub use_json_format: bool,
}
#[derive(Args, Debug)]
pub struct StartActivityArgs {
pub activity_handle: String,
}
#[derive(Args, Debug)]
pub struct SelectActivityArgs {
pub activity_id: Id,
}
#[derive(Args, Debug)]
pub struct DeleteActivityArgs {
pub id: Id,
#[arg(short = 'c', long = "confirm", action = ArgAction::SetTrue, conflicts_with = "no_confirm")]
pub confirm: bool,
#[arg(short = 'C', long = "no-confirm", action = ArgAction::SetTrue, conflicts_with = "confirm")]
pub no_confirm: bool,
}
#[derive(Args, Debug)]
pub struct CancelActivityArgs {
#[arg(short = 'c', long = "confirm", action = ArgAction::SetTrue, conflicts_with = "no_confirm")]
pub confirm: bool,
#[arg(short = 'C', long = "no-confirm", action = ArgAction::SetTrue, conflicts_with = "confirm")]
pub no_confirm: bool,
}
#[derive(Args, Debug)]
pub struct CreateActivityArgs {
pub name: String,
#[arg(short, long)]
pub description: Option<String>,
#[arg(short, long, value_delimiter = ',', action = ArgAction::Append)]
pub tags: Vec<String>,
#[arg(short = 's', long = "start-now", action = ArgAction::SetTrue, conflicts_with = "no_auto_start")]
pub auto_start: bool,
#[arg(short = 'S', long = "no-start-now", action = ArgAction::SetTrue, conflicts_with = "auto_start")]
pub no_auto_start: bool,
#[arg(short = 'j', long = "json")]
pub use_json_format: bool,
}
#[derive(Args, Debug)]
pub struct ModifyActivityArgs {
pub id: Id,
#[clap(flatten)]
pub update: UpdateGroup,
#[arg(short = 'c', long = "confirm", action = ArgAction::SetTrue, conflicts_with = "no_confirm")]
pub confirm: bool,
#[arg(short = 'C', long = "no-confirm", action = ArgAction::SetTrue, conflicts_with = "confirm")]
pub no_confirm: bool,
}
#[derive(Args, Debug)]
#[group(required = true)]
pub struct UpdateGroup {
#[arg(short = 'n', long = "name")]
pub name: Option<String>,
#[arg(short, long)]
pub description: Option<String>,
#[arg(short, long, value_delimiter = ',', action = ArgAction::Append, num_args(0..))]
pub tags: Option<Vec<String>>,
}
#[derive(Args, Debug)]
pub struct EditLogsArgs {
#[arg(
short = 'p',
long = "period",
help = "Period: day|d, week|w, month|m, year|y, <date>, or <start>..<end>"
)]
pub period: Option<PeriodInput>,
#[arg(short = 'e', long = "editor")]
pub editor: Option<String>,
#[arg(short = 'i', long = "with-instructions", alias = "with-instr", action = ArgAction::SetTrue, conflicts_with = "hide_instructions")]
pub show_instructions: bool,
#[arg(short = 'I', long = "no-instructions", alias = "no-instr", action = ArgAction::SetTrue, conflicts_with = "show_instructions")]
pub hide_instructions: bool,
#[arg(short = 'd', long = "with-activity-definitions", alias = "with-act-defs", alias = "with-defs", action = ArgAction::SetTrue, conflicts_with = "hide_activity_definitions")]
pub show_activity_definitions: bool,
#[arg(short = 'D', long = "no-activity-definitions", alias = "no-act-defs", alias = "no-defs", action = ArgAction::SetTrue, conflicts_with = "show_activity_definitions")]
pub hide_activity_definitions: bool,
#[arg(short = 'c', long = "confirm", action = ArgAction::SetTrue, conflicts_with = "no_confirm")]
pub confirm: bool,
#[arg(short = 'C', long = "no-confirm", action = ArgAction::SetTrue, conflicts_with = "confirm")]
pub no_confirm: bool,
}