seaplane_cli/context/
restrict.rs1use std::collections::HashSet;
2
3use seaplane::api::{
4 restrict::v1::{RestrictedDirectory, RestrictionDetails},
5 shared::v1::{Provider as ProviderModel, Region as RegionModel},
6};
7
8use crate::{
9 cli::cmds::restrict::{
10 common::{Provider, Region},
11 SeaplaneRestrictCommonArgMatches, SeaplaneRestrictListArgMatches,
12 SeaplaneRestrictSetArgMatches,
13 },
14 error::Result,
15};
16
17#[derive(Debug, Default, Clone)]
22pub struct RestrictCtx {
23 pub api: Option<String>,
24 pub directory: Option<RestrictedDirectory>,
26 pub from_api: Option<String>,
27 pub from_dir: Option<String>,
29 pub providers_allowed: HashSet<ProviderModel>,
31 pub providers_denied: HashSet<ProviderModel>,
33 pub regions_allowed: HashSet<RegionModel>,
35 pub regions_denied: HashSet<RegionModel>,
37 pub base64: bool,
39 pub decode: bool,
41 pub no_header: bool,
43}
44
45impl RestrictCtx {
46 pub fn from_restrict_common(matches: &SeaplaneRestrictCommonArgMatches) -> Result<RestrictCtx> {
48 let matches = matches.0;
49 let base64 = matches.get_flag("base64");
50 let api = matches.get_one::<String>("api").unwrap();
51 let dir = matches.get_one::<String>("directory").unwrap();
52
53 Ok(RestrictCtx {
54 api: Some(api.into()),
55 directory: if base64 {
56 let engine = ::base64::engine::fast_portable::FastPortable::from(
58 &::base64::alphabet::URL_SAFE,
59 ::base64::engine::fast_portable::NO_PAD,
60 );
61 let _ = base64::decode_engine(dir, &engine)?;
62 Some(RestrictedDirectory::from_encoded(dir))
63 } else {
64 Some(RestrictedDirectory::from_unencoded(dir))
65 },
66 base64: true, ..RestrictCtx::default()
68 })
69 }
70
71 pub fn from_restrict_list(matches: &SeaplaneRestrictListArgMatches) -> Result<RestrictCtx> {
73 let api = matches.0.get_one::<String>("api").map(|a| a.to_owned());
74
75 Ok(RestrictCtx { api, ..RestrictCtx::default() })
76 }
77
78 pub fn from_restrict_set(matches: &SeaplaneRestrictSetArgMatches) -> Result<RestrictCtx> {
80 let matches = matches.0;
81 let base64 = matches.get_flag("base64");
82 let raw_api = matches.get_one::<String>("api").unwrap();
83 let raw_dir = matches.get_one::<String>("directory").unwrap();
84
85 let providers_allowed: HashSet<ProviderModel> = matches
86 .get_many::<Provider>("provider")
87 .unwrap_or_default()
88 .filter_map(Provider::into_model)
89 .collect();
90 let providers_denied: HashSet<ProviderModel> = matches
91 .get_many::<Provider>("exclude-provider")
92 .unwrap_or_default()
93 .filter_map(Provider::into_model)
94 .collect();
95 let regions_allowed: HashSet<RegionModel> = matches
96 .get_many::<Region>("region")
97 .unwrap_or_default()
98 .filter_map(Region::into_model)
99 .collect();
100 let regions_denied: HashSet<RegionModel> = matches
101 .get_many::<Region>("exclude-region")
102 .unwrap_or_default()
103 .filter_map(Region::into_model)
104 .collect();
105 Ok(RestrictCtx {
106 api: Some(raw_api.into()),
107 directory: if base64 {
108 let engine = ::base64::engine::fast_portable::FastPortable::from(
110 &::base64::alphabet::URL_SAFE,
111 ::base64::engine::fast_portable::NO_PAD,
112 );
113 let _ = base64::decode_engine(raw_dir, &engine)?;
114 Some(RestrictedDirectory::from_encoded(raw_dir))
115 } else {
116 Some(RestrictedDirectory::from_unencoded(raw_dir))
117 },
118 base64: true, providers_allowed,
120 providers_denied,
121 regions_allowed,
122 regions_denied,
123 ..RestrictCtx::default()
124 })
125 }
126
127 pub fn restriction_details(&self) -> Result<RestrictionDetails> {
128 let mut builder = RestrictionDetails::builder();
129
130 for item in &self.providers_allowed {
131 builder = builder.add_allowed_provider(*item);
132 }
133 for item in &self.providers_denied {
134 builder = builder.add_denied_provider(*item);
135 }
136 for item in &self.regions_allowed {
137 builder = builder.add_allowed_region(*item);
138 }
139 for item in &self.regions_denied {
140 builder = builder.add_denied_region(*item);
141 }
142
143 Ok(builder.build()?)
144 }
145}