use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser)]
#[command(
name = "ghfetch",
about = "GitHub stats in the terminal, neofetch-style"
)]
#[command(version, arg_required_else_help = true)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Command>,
#[arg(value_name = "USERNAME")]
pub username: Option<String>,
#[arg(long, global = true, env = "GITHUB_TOKEN", hide_env_values = true)]
pub token: Option<String>,
#[arg(long, global = true)]
pub no_color: bool,
#[arg(long, global = true)]
pub json: bool,
#[arg(long, global = true, value_enum, default_value_t = Theme::Mocha)]
pub theme: Theme,
#[arg(long, short, global = true)]
pub verbose: bool,
}
#[derive(Subcommand)]
pub enum Command {
User {
username: String,
#[command(flatten)]
opts: UserOpts,
},
Repo {
repo: String,
#[command(flatten)]
opts: RepoOpts,
},
Org {
orgname: String,
#[command(flatten)]
opts: OrgOpts,
},
}
#[derive(Clone, Copy, ValueEnum)]
pub enum Theme {
Mocha,
Macchiato,
Frappe,
Latte,
}
#[derive(Clone, Copy, ValueEnum)]
pub enum SortBy {
Stars,
Forks,
Updated,
Size,
Name,
}
#[derive(Parser)]
pub struct UserOpts {
#[arg(long)]
pub languages: bool,
#[arg(long)]
pub streaks: bool,
#[arg(long)]
pub repos: bool,
#[arg(long)]
pub contributions: bool,
#[arg(long)]
pub all: bool,
#[arg(long)]
pub lang_limit: Option<usize>,
#[arg(long, default_value_t = 10)]
pub repo_limit: usize,
#[arg(long, value_enum, default_value_t = SortBy::Stars)]
pub sort_by: SortBy,
#[arg(long)]
pub no_forks: bool,
}
#[derive(Parser)]
pub struct RepoOpts {
#[arg(long)]
pub languages: bool,
#[arg(long)]
pub all: bool,
}
#[derive(Parser)]
pub struct OrgOpts {
#[arg(long)]
pub languages: bool,
#[arg(long)]
pub repos: bool,
#[arg(long)]
pub all: bool,
#[arg(long)]
pub lang_limit: Option<usize>,
#[arg(long, default_value_t = 10)]
pub repo_limit: usize,
}
impl UserOpts {
pub fn default_full() -> Self {
Self {
languages: false,
streaks: false,
repos: false,
contributions: false,
all: false,
lang_limit: None,
repo_limit: 10,
sort_by: SortBy::Stars,
no_forks: false,
}
}
pub fn show_full_card(&self) -> bool {
!self.languages && !self.streaks && !self.repos && !self.contributions && !self.all
}
pub fn show_languages(&self) -> bool {
self.all || self.languages || self.show_full_card()
}
pub fn detailed_languages(&self) -> bool {
self.languages && !self.all && !self.show_full_card()
}
pub fn effective_lang_limit(&self) -> usize {
match self.lang_limit {
Some(n) => n,
None if self.detailed_languages() => 0,
None => 10,
}
}
pub fn show_streaks(&self) -> bool {
self.all || self.streaks || self.show_full_card()
}
pub fn show_repos(&self) -> bool {
self.all || self.repos
}
pub fn show_contributions(&self) -> bool {
self.all || self.contributions || self.show_full_card()
}
}
impl RepoOpts {
pub fn show_full_card(&self) -> bool {
!self.languages && !self.all
}
pub fn show_languages(&self) -> bool {
self.all || self.languages || self.show_full_card()
}
pub fn detailed_languages(&self) -> bool {
self.languages && !self.all && !self.show_full_card()
}
}
impl OrgOpts {
pub fn show_full_card(&self) -> bool {
!self.languages && !self.repos && !self.all
}
pub fn show_languages(&self) -> bool {
self.all || self.languages || self.show_full_card()
}
pub fn detailed_languages(&self) -> bool {
self.languages && !self.all && !self.show_full_card()
}
pub fn effective_lang_limit(&self) -> usize {
match self.lang_limit {
Some(n) => n,
None if self.detailed_languages() => 0,
None => 10,
}
}
pub fn show_repos(&self) -> bool {
self.all || self.repos
}
}