use clap::{Parser, Subcommand};
use radicle::git;
use radicle::git::fmt::RefString;
use radicle::node::NodeId;
use crate::terminal as term;
const ABOUT: &str = "Manage a repository's remotes";
#[derive(Parser, Debug)]
#[command(about = ABOUT, disable_version_flag = true)]
pub struct Args {
#[command(subcommand)]
pub(super) command: Option<Command>,
#[clap(flatten)]
pub(super) empty: EmptyArgs,
}
#[derive(Subcommand, Debug)]
pub(super) enum Command {
#[clap(alias = "a")]
Add {
#[arg(value_parser = term::args::parse_nid)]
nid: NodeId,
#[arg(long, short, value_name = "REMOTE", value_parser = parse_refstr)]
name: Option<RefString>,
#[clap(flatten)]
fetch: FetchArgs,
#[clap(flatten)]
sync: SyncArgs,
},
#[clap(alias = "r")]
Rm {
#[arg(value_name = "REMOTE", value_parser = parse_refstr)]
name: RefString,
},
#[clap(alias = "l")]
List(ListArgs),
}
#[derive(Parser, Debug)]
pub(super) struct FetchArgs {
#[arg(long, conflicts_with = "no_fetch")]
fetch: bool,
#[arg(long)]
no_fetch: bool,
}
impl FetchArgs {
pub(super) fn should_fetch(&self) -> bool {
let Self { fetch, no_fetch } = self;
*fetch || !no_fetch
}
}
#[derive(Parser, Debug)]
pub(super) struct SyncArgs {
#[arg(long, conflicts_with = "no_sync")]
sync: bool,
#[arg(long)]
no_sync: bool,
}
impl SyncArgs {
pub(super) fn should_sync(&self) -> bool {
let Self { sync, no_sync } = self;
*sync || !no_sync
}
}
#[derive(Parser, Clone, Copy, Debug)]
#[group(multiple = false)]
pub struct ListArgs {
#[arg(long)]
all: bool,
#[arg(long)]
tracked: bool,
#[arg(long)]
untracked: bool,
}
impl From<ListArgs> for ListOption {
fn from(
ListArgs {
all,
tracked,
untracked,
}: ListArgs,
) -> Self {
match (all, tracked, untracked) {
(true, false, false) => Self::All,
(false, true, false) | (false, false, false) => Self::Tracked,
(false, false, true) => Self::Untracked,
_ => unreachable!(),
}
}
}
pub(super) enum ListOption {
All,
Tracked,
Untracked,
}
#[derive(Parser, Clone, Copy, Debug)]
#[group(multiple = false)]
pub(super) struct EmptyArgs {
#[arg(long, hide = true)]
all: bool,
#[arg(long, hide = true)]
tracked: bool,
#[arg(long, hide = true)]
untracked: bool,
}
impl From<EmptyArgs> for ListArgs {
fn from(args: EmptyArgs) -> Self {
Self {
all: args.all,
tracked: args.tracked,
untracked: args.untracked,
}
}
}
fn parse_refstr(refstr: &str) -> Result<RefString, git::fmt::Error> {
RefString::try_from(refstr)
}