use crate::pricing::CostMode;
use clap::{Parser, Subcommand, ValueEnum};
use std::path::PathBuf;
const CONFIG_HELP: &str = "Config";
fn default_format() -> Format {
Format::Table
}
fn default_sort() -> String {
"total".to_string()
}
fn default_cost() -> CostMode {
CostMode::Mixed
}
fn default_group_by() -> Vec<String> {
vec!["source".to_string(), "model".to_string()]
}
fn default_date_bucket() -> DateBucket {
DateBucket::Day
}
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
pub enum Format {
Table,
Json,
}
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
pub enum DateBucket {
Day,
Week,
Month,
}
impl DateBucket {
pub fn as_str(&self) -> &'static str {
match self {
DateBucket::Day => "day",
DateBucket::Week => "week",
DateBucket::Month => "month",
}
}
}
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
pub enum AvgBy {
Call,
Round,
Session,
}
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
pub enum Unit {
Tokens,
Bytes,
Cost,
}
#[derive(Debug, Parser)]
#[command(name = "llm-tokei", version, about, disable_help_flag = true)]
pub struct Args {
#[arg(long, value_enum, default_value_t = default_format(), help_heading = "Output")]
pub format: Format,
#[arg(long, default_value_t = default_sort(), help_heading = "Output")]
pub sort: String,
#[arg(long, help_heading = "Output")]
pub asc: bool,
#[arg(long, help_heading = "Output")]
pub limit: Option<usize>,
#[arg(long, help_heading = "Output")]
pub no_cost: bool,
#[arg(long, value_enum, default_value_t = default_cost(), help_heading = "Output")]
pub cost: CostMode,
#[arg(long, help_heading = "Output")]
pub cost_per: Option<String>,
#[arg(long, help_heading = "Period", conflicts_with_all = ["period_24h", "period_7d", "period_1m", "today", "week", "month"])]
pub period: Option<String>,
#[arg(long = "24h", help_heading = "Period")]
pub period_24h: bool,
#[arg(long = "7d", help_heading = "Period")]
pub period_7d: bool,
#[arg(long = "1m", help_heading = "Period")]
pub period_1m: bool,
#[arg(long, help_heading = "Period")]
pub today: bool,
#[arg(long, help_heading = "Period")]
pub week: bool,
#[arg(long, help_heading = "Period")]
pub month: bool,
#[arg(long, help_heading = "Table")]
pub no_color: bool,
#[arg(short = 'h', long, help_heading = "Table")]
pub human: bool,
#[arg(long, conflicts_with = "table_width", help_heading = "Table")]
pub no_fit: bool,
#[arg(long, help_heading = "Table")]
pub table_width: Option<usize>,
#[arg(long, help_heading = "Table")]
pub split_input: bool,
#[arg(long, value_enum, help_heading = "Table")]
pub unit: Option<Unit>,
#[arg(long, conflicts_with = "unit", help_heading = "Table")]
pub bytes: bool,
#[arg(long, value_enum, help_heading = "Table")]
pub avg: Option<AvgBy>,
#[arg(long, help_heading = "Cache")]
pub no_cache: bool,
#[arg(
long,
value_delimiter = ',',
default_values_t = default_group_by(),
help_heading = "Grouping"
)]
pub group_by: Vec<String>,
#[arg(long, value_enum, default_value_t = default_date_bucket(), help_heading = "Grouping")]
pub date_bucket: DateBucket,
#[arg(long, help_heading = CONFIG_HELP)]
pub config: Option<PathBuf>,
#[arg(long, help_heading = CONFIG_HELP)]
pub no_config: bool,
#[arg(long, help_heading = CONFIG_HELP)]
pub save_default: bool,
#[arg(long, help_heading = CONFIG_HELP)]
pub no_default: bool,
#[arg(long, help_heading = "Filters")]
pub since: Option<String>,
#[arg(long, help_heading = "Filters")]
pub until: Option<String>,
#[arg(long, help_heading = "Filters")]
pub model: Option<String>,
#[arg(long, help_heading = "Filters")]
pub provider: Option<String>,
#[arg(long, help_heading = "Filters")]
pub cwd: Option<String>,
#[arg(long, value_delimiter = ',', help_heading = "Sources")]
pub source: Option<Vec<String>>,
#[arg(long, help_heading = "Sources")]
pub codex_dir: Option<PathBuf>,
#[arg(long, help_heading = "Sources")]
pub opencode_db: Option<PathBuf>,
#[arg(long, help_heading = "Sources")]
pub claude_dir: Option<PathBuf>,
#[arg(long, help_heading = "Sources")]
pub copilot_dir: Option<Vec<PathBuf>>,
#[arg(long, help_heading = "Sources")]
pub copilot_cli_dir: Option<Vec<PathBuf>>,
#[arg(long, help_heading = "Pricing")]
pub pricing: Option<PathBuf>,
#[arg(long, action = clap::ArgAction::HelpLong, help_heading = "Diagnostics")]
pub help: Option<bool>,
#[arg(short, long, help_heading = "Diagnostics")]
pub verbose: bool,
#[command(subcommand)]
pub cmd: Option<Cmd>,
}
#[derive(Debug, Subcommand)]
pub enum Cmd {
Config {
#[command(subcommand)]
cmd: ConfigCmd,
},
Update {
#[arg(long, action = clap::ArgAction::HelpLong, help_heading = "Diagnostics")]
help: Option<bool>,
},
Dump {
#[arg(long, help_heading = "Source Selection", display_order = 10)]
copilot: bool,
#[arg(long = "copilot-cli", help_heading = "Source Selection", display_order = 11)]
copilot_cli: bool,
#[arg(long, help_heading = "Source Selection", display_order = 12)]
codex: bool,
files: Vec<PathBuf>,
#[arg(long, short = 'o', help_heading = "Output", display_order = 20)]
out: Option<PathBuf>,
#[arg(long, action = clap::ArgAction::HelpLong, help_heading = "Diagnostics", display_order = 30)]
help: Option<bool>,
},
}
#[derive(Debug, Subcommand)]
pub enum ConfigCmd {
List {
#[arg(long, action = clap::ArgAction::HelpLong, help_heading = "Diagnostics")]
help: Option<bool>,
},
Args {
args: Option<String>,
#[arg(long)]
reset: bool,
#[arg(long, action = clap::ArgAction::HelpLong, help_heading = "Diagnostics")]
help: Option<bool>,
},
}