aws_sdk_codecatalyst/config/
endpoint.rs1pub use ::aws_smithy_runtime_api::client::endpoint::EndpointFuture;
3pub use ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver;
4pub use ::aws_smithy_types::endpoint::Endpoint;
5
6#[derive(Debug, Default)]
8pub(crate) struct EndpointOverrideFeatureTrackerInterceptor;
9
10#[::aws_smithy_runtime_api::client::interceptors::dyn_dispatch_hint]
11impl ::aws_smithy_runtime_api::client::interceptors::Intercept for EndpointOverrideFeatureTrackerInterceptor {
12 fn name(&self) -> &'static str {
13 "EndpointOverrideFeatureTrackerInterceptor"
14 }
15
16 fn read_before_execution(
17 &self,
18 _context: &::aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextRef<'_>,
19 cfg: &mut ::aws_smithy_types::config_bag::ConfigBag,
20 ) -> ::std::result::Result<(), ::aws_smithy_runtime_api::box_error::BoxError> {
21 if cfg.load::<::aws_types::endpoint_config::EndpointUrl>().is_some() {
22 cfg.interceptor_state()
23 .store_append(::aws_runtime::sdk_feature::AwsSdkFeature::EndpointOverride);
24 }
25 ::std::result::Result::Ok(())
26 }
27}
28
29#[cfg(test)]
30mod test {
31
32 #[test]
34 fn test_1() {
35 let params = crate::config::endpoint::Params::builder()
36 .endpoint("https://test.codecatalyst.global.api.aws".to_string())
37 .build()
38 .expect("invalid params");
39 let resolver = crate::config::endpoint::DefaultResolver::new();
40 let endpoint = resolver.resolve_endpoint(¶ms);
41 let endpoint = endpoint.expect("Expected valid endpoint: https://test.codecatalyst.global.api.aws");
42 assert_eq!(
43 endpoint,
44 ::aws_smithy_types::endpoint::Endpoint::builder()
45 .url("https://test.codecatalyst.global.api.aws")
46 .build()
47 );
48 }
49
50 #[test]
52 fn test_2() {
53 let params = crate::config::endpoint::Params::builder().build().expect("invalid params");
54 let resolver = crate::config::endpoint::DefaultResolver::new();
55 let endpoint = resolver.resolve_endpoint(¶ms);
56 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst.global.api.aws");
57 assert_eq!(
58 endpoint,
59 ::aws_smithy_types::endpoint::Endpoint::builder()
60 .url("https://codecatalyst.global.api.aws")
61 .build()
62 );
63 }
64
65 #[test]
67 fn test_3() {
68 let params = crate::config::endpoint::Params::builder().use_fips(true).build().expect("invalid params");
69 let resolver = crate::config::endpoint::DefaultResolver::new();
70 let endpoint = resolver.resolve_endpoint(¶ms);
71 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst-fips.global.api.aws");
72 assert_eq!(
73 endpoint,
74 ::aws_smithy_types::endpoint::Endpoint::builder()
75 .url("https://codecatalyst-fips.global.api.aws")
76 .build()
77 );
78 }
79
80 #[test]
82 fn test_4() {
83 let params = crate::config::endpoint::Params::builder()
84 .region("aws-global".to_string())
85 .build()
86 .expect("invalid params");
87 let resolver = crate::config::endpoint::DefaultResolver::new();
88 let endpoint = resolver.resolve_endpoint(¶ms);
89 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst.global.api.aws");
90 assert_eq!(
91 endpoint,
92 ::aws_smithy_types::endpoint::Endpoint::builder()
93 .url("https://codecatalyst.global.api.aws")
94 .build()
95 );
96 }
97
98 #[test]
100 fn test_5() {
101 let params = crate::config::endpoint::Params::builder()
102 .region("aws-global".to_string())
103 .use_fips(true)
104 .build()
105 .expect("invalid params");
106 let resolver = crate::config::endpoint::DefaultResolver::new();
107 let endpoint = resolver.resolve_endpoint(¶ms);
108 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst-fips.global.api.aws");
109 assert_eq!(
110 endpoint,
111 ::aws_smithy_types::endpoint::Endpoint::builder()
112 .url("https://codecatalyst-fips.global.api.aws")
113 .build()
114 );
115 }
116
117 #[test]
119 fn test_6() {
120 let params = crate::config::endpoint::Params::builder()
121 .region("us-west-2".to_string())
122 .build()
123 .expect("invalid params");
124 let resolver = crate::config::endpoint::DefaultResolver::new();
125 let endpoint = resolver.resolve_endpoint(¶ms);
126 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst.global.api.aws");
127 assert_eq!(
128 endpoint,
129 ::aws_smithy_types::endpoint::Endpoint::builder()
130 .url("https://codecatalyst.global.api.aws")
131 .build()
132 );
133 }
134
135 #[test]
137 fn test_7() {
138 let params = crate::config::endpoint::Params::builder()
139 .region("us-west-2".to_string())
140 .use_fips(true)
141 .build()
142 .expect("invalid params");
143 let resolver = crate::config::endpoint::DefaultResolver::new();
144 let endpoint = resolver.resolve_endpoint(¶ms);
145 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst-fips.global.api.aws");
146 assert_eq!(
147 endpoint,
148 ::aws_smithy_types::endpoint::Endpoint::builder()
149 .url("https://codecatalyst-fips.global.api.aws")
150 .build()
151 );
152 }
153
154 #[test]
156 fn test_8() {
157 let params = crate::config::endpoint::Params::builder()
158 .region("us-east-1".to_string())
159 .build()
160 .expect("invalid params");
161 let resolver = crate::config::endpoint::DefaultResolver::new();
162 let endpoint = resolver.resolve_endpoint(¶ms);
163 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst.global.api.aws");
164 assert_eq!(
165 endpoint,
166 ::aws_smithy_types::endpoint::Endpoint::builder()
167 .url("https://codecatalyst.global.api.aws")
168 .build()
169 );
170 }
171
172 #[test]
174 fn test_9() {
175 let params = crate::config::endpoint::Params::builder()
176 .region("us-east-1".to_string())
177 .use_fips(true)
178 .build()
179 .expect("invalid params");
180 let resolver = crate::config::endpoint::DefaultResolver::new();
181 let endpoint = resolver.resolve_endpoint(¶ms);
182 let endpoint = endpoint.expect("Expected valid endpoint: https://codecatalyst-fips.global.api.aws");
183 assert_eq!(
184 endpoint,
185 ::aws_smithy_types::endpoint::Endpoint::builder()
186 .url("https://codecatalyst-fips.global.api.aws")
187 .build()
188 );
189 }
190}
191
192pub trait ResolveEndpoint: ::std::marker::Send + ::std::marker::Sync + ::std::fmt::Debug {
194 fn resolve_endpoint<'a>(&'a self, params: &'a crate::config::endpoint::Params) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a>;
196
197 fn into_shared_resolver(self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver
201 where
202 Self: Sized + 'static,
203 {
204 ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver::new(DowncastParams(self))
205 }
206}
207
208#[derive(Debug)]
209struct DowncastParams<T>(T);
210impl<T> ::aws_smithy_runtime_api::client::endpoint::ResolveEndpoint for DowncastParams<T>
211where
212 T: ResolveEndpoint,
213{
214 fn resolve_endpoint<'a>(
215 &'a self,
216 params: &'a ::aws_smithy_runtime_api::client::endpoint::EndpointResolverParams,
217 ) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a> {
218 let ep = match params.get::<crate::config::endpoint::Params>() {
219 Some(params) => self.0.resolve_endpoint(params),
220 None => ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(Err("params of expected type was not present".into())),
221 };
222 ep
223 }
224}
225
226#[derive(Debug)]
227pub struct DefaultResolver {
229 partition_resolver: &'static crate::endpoint_lib::partition::PartitionResolver,
230 endpoint_cache: ::arc_swap::ArcSwap<::std::option::Option<(Params, ::aws_smithy_types::endpoint::Endpoint)>>,
231}
232
233impl Default for DefaultResolver {
234 fn default() -> Self {
235 Self::new()
236 }
237}
238
239impl DefaultResolver {
240 pub fn new() -> Self {
242 Self {
243 partition_resolver: &crate::endpoint_lib::DEFAULT_PARTITION_RESOLVER,
244 endpoint_cache: ::arc_swap::ArcSwap::from_pointee(None),
245 }
246 }
247
248 #[allow(
249 unused_variables,
250 unused_parens,
251 clippy::double_parens,
252 clippy::useless_conversion,
253 clippy::bool_comparison,
254 clippy::comparison_to_empty,
255 clippy::needless_borrow,
256 clippy::useless_asref,
257 clippy::redundant_closure_call,
258 clippy::clone_on_copy,
259 clippy::single_char_add_str
260 )]
261 fn resolve_endpoint<'a>(
262 &'a self,
263 params: &'a crate::config::endpoint::Params,
264 ) -> ::std::result::Result<::aws_smithy_types::endpoint::Endpoint, ::aws_smithy_runtime_api::box_error::BoxError> {
265 let mut _diagnostic_collector = crate::endpoint_lib::diagnostic::DiagnosticCollector::new();
266 #[allow(unused_mut)]
267 let mut context = ConditionContext::default();
268
269 let use_fips = ¶ms.use_fips;
271 let region = ¶ms.region;
272 let endpoint = ¶ms.endpoint;
273
274 let mut current_ref: i32 = 2;
275 loop {
276 match current_ref {
277 ref_val if ref_val >= 100_000_000 => {
278 return match (ref_val - 100_000_000) as usize {
279 0 => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
280 "No endpoint rule matched",
281 )) as ::aws_smithy_runtime_api::box_error::BoxError),
282 1 => {
283 let endpoint = params.endpoint.as_deref().unwrap_or_default();
284 ::std::result::Result::Ok(::aws_smithy_types::endpoint::Endpoint::builder().url(endpoint.to_owned()).build())
285 }
286 2 => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
287 "Partition does not support FIPS.".to_string(),
288 )) as ::aws_smithy_runtime_api::box_error::BoxError),
289 3 => {
290 let partition_result_ssa_1 = context
291 .partition_result_ssa_1
292 .as_ref()
293 .expect("Guaranteed to have a value by earlier checks.");
294 ::std::result::Result::Ok(
295 ::aws_smithy_types::endpoint::Endpoint::builder()
296 .url({
297 let mut out = String::new();
298 out.push_str("https://codecatalyst-fips.global.");
299 #[allow(clippy::needless_borrow)]
300 out.push_str(&partition_result_ssa_1.dual_stack_dns_suffix());
301 out
302 })
303 .build(),
304 )
305 }
306 4 => {
307 let partition_result_ssa_1 = context
308 .partition_result_ssa_1
309 .as_ref()
310 .expect("Guaranteed to have a value by earlier checks.");
311 ::std::result::Result::Ok(
312 ::aws_smithy_types::endpoint::Endpoint::builder()
313 .url({
314 let mut out = String::new();
315 out.push_str("https://codecatalyst.global.");
316 #[allow(clippy::needless_borrow)]
317 out.push_str(&partition_result_ssa_1.dual_stack_dns_suffix());
318 out
319 })
320 .build(),
321 )
322 }
323 5 => {
324 let partition_result_ssa_2 = context
325 .partition_result_ssa_2
326 .as_ref()
327 .expect("Guaranteed to have a value by earlier checks.");
328 ::std::result::Result::Ok(
329 ::aws_smithy_types::endpoint::Endpoint::builder()
330 .url({
331 let mut out = String::new();
332 out.push_str("https://codecatalyst-fips.global.");
333 #[allow(clippy::needless_borrow)]
334 out.push_str(&partition_result_ssa_2.dual_stack_dns_suffix());
335 out
336 })
337 .build(),
338 )
339 }
340 6 => {
341 let partition_result_ssa_2 = context
342 .partition_result_ssa_2
343 .as_ref()
344 .expect("Guaranteed to have a value by earlier checks.");
345 ::std::result::Result::Ok(
346 ::aws_smithy_types::endpoint::Endpoint::builder()
347 .url({
348 let mut out = String::new();
349 out.push_str("https://codecatalyst.global.");
350 #[allow(clippy::needless_borrow)]
351 out.push_str(&partition_result_ssa_2.dual_stack_dns_suffix());
352 out
353 })
354 .build(),
355 )
356 }
357 _ => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
358 "No endpoint rule matched",
359 )) as ::aws_smithy_runtime_api::box_error::BoxError),
360 };
361 }
362 1 | -1 => {
363 return ::std::result::Result::Err(
364 Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("No endpoint rule matched"))
365 as ::aws_smithy_runtime_api::box_error::BoxError,
366 )
367 }
368 ref_val => {
369 let is_complement = ref_val < 0;
370 let node = &NODES[(ref_val.unsigned_abs() as usize) - 1];
371 let condition_result = match node.condition_index {
372 0 => endpoint.is_some(),
373 1 => region.is_some(),
374 2 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
375 let partition_result_ssa_2 = &mut context.partition_result_ssa_2;
376 let partition_resolver = &self.partition_resolver;
377 {
378 *partition_result_ssa_2 = partition_resolver
379 .resolve_partition(if let Some(param) = region { param } else { return false }, _diagnostic_collector)
380 .map(|inner| inner.into());
381 partition_result_ssa_2.is_some()
382 }
383 })(&mut _diagnostic_collector),
384 3 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
385 let partition_result_ssa_1 = &mut context.partition_result_ssa_1;
386 let partition_resolver = &self.partition_resolver;
387 {
388 *partition_result_ssa_1 = partition_resolver
389 .resolve_partition("us-west-2", _diagnostic_collector)
390 .map(|inner| inner.into());
391 partition_result_ssa_1.is_some()
392 }
393 })(&mut _diagnostic_collector),
394 4 => (use_fips) == (&true),
395 5 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
396 let partition_result_ssa_1 = &context.partition_result_ssa_1;
397 let partition_resolver = &self.partition_resolver;
398 (if let Some(inner) = partition_result_ssa_1 {
399 inner.supports_fips()
400 } else {
401 return false;
402 }) == (true)
403 })(&mut _diagnostic_collector),
404 6 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
405 let partition_result_ssa_2 = &context.partition_result_ssa_2;
406 let partition_resolver = &self.partition_resolver;
407 (if let Some(inner) = partition_result_ssa_2 {
408 inner.supports_fips()
409 } else {
410 return false;
411 }) == (true)
412 })(&mut _diagnostic_collector),
413 _ => unreachable!("Invalid condition index"),
414 };
415 current_ref = if is_complement ^ condition_result { node.high_ref } else { node.low_ref };
416 }
417 }
418 }
419 }
420}
421
422impl crate::config::endpoint::ResolveEndpoint for DefaultResolver {
423 fn resolve_endpoint<'a>(&'a self, params: &'a crate::config::endpoint::Params) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a> {
424 let cached = self.endpoint_cache.load();
426 if let Some((cached_params, cached_endpoint)) = cached.as_ref() {
427 if cached_params == params {
428 return ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(::std::result::Result::Ok(cached_endpoint.clone()));
429 }
430 }
431 drop(cached);
432 let result = self.resolve_endpoint(params);
433 if let ::std::result::Result::Ok(ref endpoint) = result {
434 self.endpoint_cache.store(::std::sync::Arc::new(Some((params.clone(), endpoint.clone()))));
435 }
436 ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(result)
437 }
438}
439const NODES: [crate::endpoint_lib::bdd_interpreter::BddNode; 9] = [
440 crate::endpoint_lib::bdd_interpreter::BddNode {
441 condition_index: -1,
442 high_ref: 1,
443 low_ref: -1,
444 },
445 crate::endpoint_lib::bdd_interpreter::BddNode {
446 condition_index: 0,
447 high_ref: 100000001,
448 low_ref: 3,
449 },
450 crate::endpoint_lib::bdd_interpreter::BddNode {
451 condition_index: 1,
452 high_ref: 7,
453 low_ref: 4,
454 },
455 crate::endpoint_lib::bdd_interpreter::BddNode {
456 condition_index: 3,
457 high_ref: 5,
458 low_ref: 100000000,
459 },
460 crate::endpoint_lib::bdd_interpreter::BddNode {
461 condition_index: 4,
462 high_ref: 6,
463 low_ref: 100000004,
464 },
465 crate::endpoint_lib::bdd_interpreter::BddNode {
466 condition_index: 5,
467 high_ref: 100000003,
468 low_ref: 100000002,
469 },
470 crate::endpoint_lib::bdd_interpreter::BddNode {
471 condition_index: 2,
472 high_ref: 8,
473 low_ref: 100000000,
474 },
475 crate::endpoint_lib::bdd_interpreter::BddNode {
476 condition_index: 4,
477 high_ref: 9,
478 low_ref: 100000006,
479 },
480 crate::endpoint_lib::bdd_interpreter::BddNode {
481 condition_index: 6,
482 high_ref: 100000005,
483 low_ref: 100000002,
484 },
485];
486#[derive(Default)]
489#[allow(unused_lifetimes)]
490pub(crate) struct ConditionContext<'a> {
491 pub(crate) partition_result_ssa_2: Option<crate::endpoint_lib::partition::Partition<'a>>,
492 pub(crate) partition_result_ssa_1: Option<crate::endpoint_lib::partition::Partition<'a>>,
493 phantom: std::marker::PhantomData<&'a ()>,
495}
496
497#[non_exhaustive]
498#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
499pub struct Params {
501 pub(crate) use_fips: bool,
503 pub(crate) region: ::std::option::Option<::std::string::String>,
505 pub(crate) endpoint: ::std::option::Option<::std::string::String>,
507}
508impl Params {
509 pub fn builder() -> crate::config::endpoint::ParamsBuilder {
511 crate::config::endpoint::ParamsBuilder::default()
512 }
513 pub fn use_fips(&self) -> ::std::option::Option<bool> {
515 Some(self.use_fips)
516 }
517 pub fn region(&self) -> ::std::option::Option<&str> {
519 self.region.as_deref()
520 }
521 pub fn endpoint(&self) -> ::std::option::Option<&str> {
523 self.endpoint.as_deref()
524 }
525}
526
527#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug)]
529pub struct ParamsBuilder {
530 use_fips: ::std::option::Option<bool>,
531 region: ::std::option::Option<::std::string::String>,
532 endpoint: ::std::option::Option<::std::string::String>,
533}
534impl ParamsBuilder {
535 pub fn build(self) -> ::std::result::Result<crate::config::endpoint::Params, crate::config::endpoint::InvalidParams> {
537 if let Some(region) = &self.region {
538 if !crate::endpoint_lib::host::is_valid_host_label(
539 region.as_ref() as &str,
540 true,
541 &mut crate::endpoint_lib::diagnostic::DiagnosticCollector::new(),
542 ) {
543 return Err(crate::config::endpoint::InvalidParams::invalid_value(
544 "region",
545 "must be a valid host label",
546 ));
547 }
548 };
549 Ok(
550 #[allow(clippy::unnecessary_lazy_evaluations)]
551 crate::config::endpoint::Params {
552 use_fips: self
553 .use_fips
554 .or_else(|| Some(false))
555 .ok_or_else(|| crate::config::endpoint::InvalidParams::missing("use_fips"))?,
556 region: self.region,
557 endpoint: self.endpoint,
558 },
559 )
560 }
561 pub fn use_fips(mut self, value: impl Into<bool>) -> Self {
566 self.use_fips = Some(value.into());
567 self
568 }
569
570 pub fn set_use_fips(mut self, param: Option<bool>) -> Self {
575 self.use_fips = param;
576 self
577 }
578 pub fn region(mut self, value: impl Into<::std::string::String>) -> Self {
582 self.region = Some(value.into());
583 self
584 }
585
586 pub fn set_region(mut self, param: Option<::std::string::String>) -> Self {
590 self.region = param;
591 self
592 }
593 pub fn endpoint(mut self, value: impl Into<::std::string::String>) -> Self {
597 self.endpoint = Some(value.into());
598 self
599 }
600
601 pub fn set_endpoint(mut self, param: Option<::std::string::String>) -> Self {
605 self.endpoint = param;
606 self
607 }
608}
609
610#[derive(Debug)]
612pub struct InvalidParams {
613 field: std::borrow::Cow<'static, str>,
614 kind: InvalidParamsErrorKind,
615}
616
617#[derive(Debug)]
619enum InvalidParamsErrorKind {
620 MissingField,
621 InvalidValue { message: &'static str },
622}
623
624impl InvalidParams {
625 #[allow(dead_code)]
626 fn missing(field: &'static str) -> Self {
627 Self {
628 field: field.into(),
629 kind: InvalidParamsErrorKind::MissingField,
630 }
631 }
632
633 #[allow(dead_code)]
634 fn invalid_value(field: &'static str, message: &'static str) -> Self {
635 Self {
636 field: field.into(),
637 kind: InvalidParamsErrorKind::InvalidValue { message },
638 }
639 }
640}
641
642impl std::fmt::Display for InvalidParams {
643 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
644 match self.kind {
645 InvalidParamsErrorKind::MissingField => write!(f, "a required field was missing: `{}`", self.field),
646 InvalidParamsErrorKind::InvalidValue { message } => write!(f, "invalid value for field: `{}` - {}", self.field, message),
647 }
648 }
649}
650
651impl std::error::Error for InvalidParams {}