use clap::Parser;
use clap_complete::{ArgValueCandidates, CompletionCandidate};
use git2::Repository;
use crate::git;
#[derive(Debug, Parser)]
#[command(version, about)]
#[command(rename_all = "kebab-case")]
pub struct Opt {
#[arg(short, long, add = ArgValueCandidates::new(complete_branches))]
pub branch: Option<String>,
#[arg(short, long, add = ArgValueCandidates::new(complete_tags))]
pub tag: Option<String>,
#[arg(short = 'M', long = "merge-request", conflicts_with_all = ["commit", "tag", "branch"])]
pub merge_request: bool,
#[arg(short, long)]
pub commit: Option<String>,
#[arg(short = 'B', long, env = "BROWSER")]
pub browser: Option<String>,
#[arg(short, long, add = ArgValueCandidates::new(complete_remotes))]
pub remote: Option<String>,
#[arg(short, long)]
pub verbose: bool,
}
fn complete_branches() -> Vec<CompletionCandidate> {
complete_with(git::get_branches)
}
fn complete_tags() -> Vec<CompletionCandidate> {
complete_with(git::get_tags)
}
fn complete_remotes() -> Vec<CompletionCandidate> {
complete_with(git::get_remotes)
}
fn complete_with(get_values: fn(&Repository) -> Vec<String>) -> Vec<CompletionCandidate> {
git::get_repo()
.map(|repo| {
get_values(&repo)
.into_iter()
.map(CompletionCandidate::new)
.collect()
})
.unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
use clap::CommandFactory;
#[test]
fn test_options_are_valid() {
Opt::command().debug_assert();
}
}