use clap::{builder::PossibleValue, value_parser, Arg, ArgMatches};
use seaplane::api::shared::v1::{Provider as ProviderModel, Region as RegionModel};
use crate::OutputFormat;
const LONG_DECODE: &str = "Decode the directories before printing them
Binary values will be written directly to standard output (which may do strange
things to your terminal)";
static LONG_REGION: &str = "A region where the data placement is allowed (See REGION SPEC below)
Multiple items can be passed as a comma separated list, or by using the argument
multiple times.";
static LONG_PROVIDER: &str = "A provider where the data placement is allowed
Multiple items can be passed as a comma separated list, or by using the argument
multiple times.";
static LONG_EXCLUDE_PROVIDER: &str = "A provider where the data placement is *NOT* allowed
This will override any values given to --provider
Multiple items can be passed as a comma separated list, or by using the argument
multiple times.";
static LONG_EXCLUDE_REGION: &str =
"A region where the data placement is *NOT* allowed (See REGION SPEC below)
This will override any values given to --region
Multiple items can be passed as a comma separated list, or by using the argument
multiple times.";
#[derive(Debug, Copy, Clone, PartialEq, Eq, strum::EnumString)]
#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
pub enum Provider {
Aws,
Azure,
DigitalOcean,
Equinix,
Gcp,
All,
}
impl clap::ValueEnum for Provider {
fn value_variants<'a>() -> &'a [Self] {
use Provider::*;
&[Aws, Azure, DigitalOcean, Equinix, Gcp, All]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
use Provider::*;
match self {
Aws => Some(PossibleValue::new("aws")),
Azure => Some(PossibleValue::new("azure")),
DigitalOcean => Some(PossibleValue::new("digitalocean")),
Equinix => Some(PossibleValue::new("equinix")),
Gcp => Some(PossibleValue::new("gcp")),
All => Some(PossibleValue::new("all")),
}
}
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
input.parse().map_err(|e| format!("{e}"))
}
}
impl Provider {
pub fn into_model(&self) -> Option<ProviderModel> {
if self == &Provider::All {
None
} else {
Some(self.into())
}
}
}
#[allow(clippy::from_over_into)]
impl<'a> Into<ProviderModel> for &'a Provider {
fn into(self) -> ProviderModel {
use Provider::*;
match self {
Aws => ProviderModel::AWS,
Azure => ProviderModel::Azure,
DigitalOcean => ProviderModel::DigitalOcean,
Equinix => ProviderModel::Equinix,
Gcp => ProviderModel::GCP,
All => {
panic!("Provider::All cannot be converted into seaplane::api::shared::v1::Provider")
}
}
}
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, strum::EnumString)]
#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
pub enum Region {
XA,
Asia,
XC,
PRC,
PeoplesRepublicOfChina,
XE,
Europe,
EU,
XF,
Africa,
XN,
NorthAmerica,
NAmerica,
XO,
Oceania,
XQ,
Antarctica,
XS,
SAmerica,
SouthAmerica,
XU,
UK,
UnitedKingdom,
All,
}
impl clap::ValueEnum for Region {
fn value_variants<'a>() -> &'a [Self] {
use Region::*;
&[
XA, XC, XE, XF, XN, XO, XQ, XS, XU, All,
]
}
fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
use Region::*;
match self {
XA => Some(PossibleValue::new("xa").alias("asia")),
Asia => None,
XC => Some(PossibleValue::new("xc").aliases([
"prc",
"china",
"peoples-republic-of-china",
"peoples_republic_of_china",
"peoplesrepublicofchina",
])),
PRC => None,
PeoplesRepublicOfChina => None,
XE => Some(PossibleValue::new("xe").aliases(["europe", "eu"])),
Europe => None,
EU => None,
XF => Some(PossibleValue::new("xf").alias("africa")),
Africa => None,
XN => Some(PossibleValue::new("xn").aliases([
"namerica",
"northamerica",
"n-america",
"north-america",
"n_america",
"north_america",
])),
NorthAmerica => None,
NAmerica => None,
XO => Some(PossibleValue::new("xo").alias("oceania")),
Oceania => None,
XQ => Some(PossibleValue::new("xq").alias("antarctica")),
Antarctica => None,
XS => Some(PossibleValue::new("xs").aliases([
"samerica",
"southamerica",
"s-america",
"south-america",
"s_america",
"south_america",
])),
SAmerica => None,
SouthAmerica => None,
XU => Some(PossibleValue::new("xu").aliases([
"uk",
"unitedkingdom",
"united-kingdom",
"united_kingdom",
])),
UK => None,
UnitedKingdom => None,
All => Some(PossibleValue::new("all")),
}
}
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
input.parse().map_err(|e| format!("{e}"))
}
}
impl Region {
pub fn into_model(&self) -> Option<RegionModel> {
if self == &Region::All {
None
} else {
Some(self.into())
}
}
}
#[allow(clippy::from_over_into)]
impl<'a> Into<RegionModel> for &'a Region {
fn into(self) -> RegionModel {
use Region::*;
match self {
XA | Asia => RegionModel::XA,
XC | PRC | PeoplesRepublicOfChina => RegionModel::XC,
XE | Europe | EU => RegionModel::XE,
XF | Africa => RegionModel::XF,
XN | NorthAmerica | NAmerica => RegionModel::XN,
XO | Oceania => RegionModel::XO,
XQ | Antarctica => RegionModel::XQ,
XS | SAmerica | SouthAmerica => RegionModel::XS,
XU | UK | UnitedKingdom => RegionModel::XU,
All => panic!("Region::All cannot be converted into seaplane::api::shared::v1::Region"),
}
}
}
#[allow(missing_debug_implementations)]
#[derive(Debug)]
pub struct SeaplaneRestrictCommonArgMatches<'a>(pub &'a ArgMatches);
pub fn display_args() -> Vec<Arg> {
vec![
arg!(--format =["FORMAT"=>"table"] global)
.help("Change the output format")
.value_parser(value_parser!(OutputFormat)),
arg!(--decode - ('D'))
.help("Decode the directories before printing them")
.long_help(LONG_DECODE)
.overrides_with("no-decode"),
arg!(--("no-decode"))
.help("Print directories without decoding them")
.overrides_with("decode"),
arg!(--("no-header") | ("no-heading") | ("no-headers"))
.help("Omit the header when printing with `--format=table`"),
]
}
pub fn restriction_details() -> Vec<Arg> {
vec![
arg!(--provider|providers =["PROVIDER"=>"all"]... ignore_case)
.display_order(1)
.next_line_help(true)
.help("A provider where the data placement is allowed (supports comma separated list, or multiple uses)")
.long_help(LONG_PROVIDER)
.value_parser(value_parser!(Provider)),
arg!(--("exclude-provider")|("exclude-providers") =["PROVIDER"]... ignore_case)
.display_order(2)
.next_line_help(true)
.help("A provider where the data placement is *NOT* allowed (supports comma separated list, or multiple uses)")
.long_help(LONG_EXCLUDE_PROVIDER)
.value_parser(value_parser!(Provider)),
arg!(--region|regions =["REGION"=>"all"]... ignore_case)
.display_order(1)
.next_line_help(true)
.help("A region where the data placement is allowed (supports comma separated list, or multiple uses) (See REGION SPEC below)")
.long_help(LONG_REGION)
.value_parser(value_parser!(Region)),
arg!(--("exclude-region")|("exclude-regions") =["REGION"]... ignore_case)
.display_order(2)
.next_line_help(true)
.help("A region where the data placement is *NOT* allowed (supports comma separated list, or multiple uses) (See REGION SPEC below)")
.long_help(LONG_EXCLUDE_REGION)
.value_parser(value_parser!(Region)),
]
}
pub fn base64() -> Arg {
arg!(--base64 - ('B')).help("The directory is already encoded in URL safe Base64")
}
pub fn api() -> Arg { arg!(api =["API"] required ).help("The API of the restricted directory") }
pub fn directory() -> Arg {
arg!(directory =["DIRECTORY"] required ).help("The restricted directory")
}