use std::collections::HashSet;
use seaplane::api::{
restrict::v1::{RestrictedDirectory, RestrictionDetails},
shared::v1::{Provider as ProviderModel, Region as RegionModel},
};
use crate::{
cli::cmds::restrict::{
common::{Provider, Region},
SeaplaneRestrictCommonArgMatches, SeaplaneRestrictListArgMatches,
SeaplaneRestrictSetArgMatches,
},
error::Result,
};
#[derive(Debug, Default, Clone)]
pub struct RestrictCtx {
pub api: Option<String>,
pub directory: Option<RestrictedDirectory>,
pub from_api: Option<String>,
pub from_dir: Option<String>,
pub providers_allowed: HashSet<ProviderModel>,
pub providers_denied: HashSet<ProviderModel>,
pub regions_allowed: HashSet<RegionModel>,
pub regions_denied: HashSet<RegionModel>,
pub base64: bool,
pub decode: bool,
pub no_header: bool,
}
impl RestrictCtx {
pub fn from_restrict_common(matches: &SeaplaneRestrictCommonArgMatches) -> Result<RestrictCtx> {
let matches = matches.0;
let base64 = matches.get_flag("base64");
let api = matches.get_one::<String>("api").unwrap();
let dir = matches.get_one::<String>("directory").unwrap();
Ok(RestrictCtx {
api: Some(api.into()),
directory: if base64 {
let engine = ::base64::engine::fast_portable::FastPortable::from(
&::base64::alphabet::URL_SAFE,
::base64::engine::fast_portable::NO_PAD,
);
let _ = base64::decode_engine(dir, &engine)?;
Some(RestrictedDirectory::from_encoded(dir))
} else {
Some(RestrictedDirectory::from_unencoded(dir))
},
base64: true, ..RestrictCtx::default()
})
}
pub fn from_restrict_list(matches: &SeaplaneRestrictListArgMatches) -> Result<RestrictCtx> {
let api = matches.0.get_one::<String>("api").map(|a| a.to_owned());
Ok(RestrictCtx { api, ..RestrictCtx::default() })
}
pub fn from_restrict_set(matches: &SeaplaneRestrictSetArgMatches) -> Result<RestrictCtx> {
let matches = matches.0;
let base64 = matches.get_flag("base64");
let raw_api = matches.get_one::<String>("api").unwrap();
let raw_dir = matches.get_one::<String>("directory").unwrap();
let providers_allowed: HashSet<ProviderModel> = matches
.get_many::<Provider>("provider")
.unwrap_or_default()
.filter_map(Provider::into_model)
.collect();
let providers_denied: HashSet<ProviderModel> = matches
.get_many::<Provider>("exclude-provider")
.unwrap_or_default()
.filter_map(Provider::into_model)
.collect();
let regions_allowed: HashSet<RegionModel> = matches
.get_many::<Region>("region")
.unwrap_or_default()
.filter_map(Region::into_model)
.collect();
let regions_denied: HashSet<RegionModel> = matches
.get_many::<Region>("exclude-region")
.unwrap_or_default()
.filter_map(Region::into_model)
.collect();
Ok(RestrictCtx {
api: Some(raw_api.into()),
directory: if base64 {
let engine = ::base64::engine::fast_portable::FastPortable::from(
&::base64::alphabet::URL_SAFE,
::base64::engine::fast_portable::NO_PAD,
);
let _ = base64::decode_engine(raw_dir, &engine)?;
Some(RestrictedDirectory::from_encoded(raw_dir))
} else {
Some(RestrictedDirectory::from_unencoded(raw_dir))
},
base64: true, providers_allowed,
providers_denied,
regions_allowed,
regions_denied,
..RestrictCtx::default()
})
}
pub fn restriction_details(&self) -> Result<RestrictionDetails> {
let mut builder = RestrictionDetails::builder();
for item in &self.providers_allowed {
builder = builder.add_allowed_provider(*item);
}
for item in &self.providers_denied {
builder = builder.add_denied_provider(*item);
}
for item in &self.regions_allowed {
builder = builder.add_allowed_region(*item);
}
for item in &self.regions_denied {
builder = builder.add_denied_region(*item);
}
Ok(builder.build()?)
}
}