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 )]
260 fn resolve_endpoint<'a>(
261 &'a self,
262 params: &'a crate::config::endpoint::Params,
263 ) -> ::std::result::Result<::aws_smithy_types::endpoint::Endpoint, ::aws_smithy_runtime_api::box_error::BoxError> {
264 let mut _diagnostic_collector = crate::endpoint_lib::diagnostic::DiagnosticCollector::new();
265 #[allow(unused_mut)]
266 let mut context = ConditionContext::default();
267
268 let use_fips = ¶ms.use_fips;
270 let region = ¶ms.region;
271 let endpoint = ¶ms.endpoint;
272
273 let mut current_ref: i32 = 2;
274 loop {
275 match current_ref {
276 ref_val if ref_val >= 100_000_000 => {
277 return match (ref_val - 100_000_000) as usize {
278 0 => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
279 "No endpoint rule matched",
280 )) as ::aws_smithy_runtime_api::box_error::BoxError),
281 1 => {
282 let endpoint = params.endpoint.as_deref().unwrap_or_default();
283 ::std::result::Result::Ok(::aws_smithy_types::endpoint::Endpoint::builder().url(endpoint.to_owned()).build())
284 }
285 2 => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
286 "Partition does not support FIPS.".to_string(),
287 )) as ::aws_smithy_runtime_api::box_error::BoxError),
288 3 => {
289 let partition_result_ssa_1 = context
290 .partition_result_ssa_1
291 .as_ref()
292 .expect("Guaranteed to have a value by earlier checks.");
293 ::std::result::Result::Ok(
294 ::aws_smithy_types::endpoint::Endpoint::builder()
295 .url({
296 let mut out = String::new();
297 out.push_str("https://codecatalyst-fips.global.");
298 #[allow(clippy::needless_borrow)]
299 out.push_str(&partition_result_ssa_1.dual_stack_dns_suffix());
300 out
301 })
302 .build(),
303 )
304 }
305 4 => {
306 let partition_result_ssa_1 = context
307 .partition_result_ssa_1
308 .as_ref()
309 .expect("Guaranteed to have a value by earlier checks.");
310 ::std::result::Result::Ok(
311 ::aws_smithy_types::endpoint::Endpoint::builder()
312 .url({
313 let mut out = String::new();
314 out.push_str("https://codecatalyst.global.");
315 #[allow(clippy::needless_borrow)]
316 out.push_str(&partition_result_ssa_1.dual_stack_dns_suffix());
317 out
318 })
319 .build(),
320 )
321 }
322 5 => {
323 let partition_result_ssa_2 = context
324 .partition_result_ssa_2
325 .as_ref()
326 .expect("Guaranteed to have a value by earlier checks.");
327 ::std::result::Result::Ok(
328 ::aws_smithy_types::endpoint::Endpoint::builder()
329 .url({
330 let mut out = String::new();
331 out.push_str("https://codecatalyst-fips.global.");
332 #[allow(clippy::needless_borrow)]
333 out.push_str(&partition_result_ssa_2.dual_stack_dns_suffix());
334 out
335 })
336 .build(),
337 )
338 }
339 6 => {
340 let partition_result_ssa_2 = context
341 .partition_result_ssa_2
342 .as_ref()
343 .expect("Guaranteed to have a value by earlier checks.");
344 ::std::result::Result::Ok(
345 ::aws_smithy_types::endpoint::Endpoint::builder()
346 .url({
347 let mut out = String::new();
348 out.push_str("https://codecatalyst.global.");
349 #[allow(clippy::needless_borrow)]
350 out.push_str(&partition_result_ssa_2.dual_stack_dns_suffix());
351 out
352 })
353 .build(),
354 )
355 }
356 _ => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message(
357 "No endpoint rule matched",
358 )) as ::aws_smithy_runtime_api::box_error::BoxError),
359 };
360 }
361 1 | -1 => {
362 return ::std::result::Result::Err(
363 Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("No endpoint rule matched"))
364 as ::aws_smithy_runtime_api::box_error::BoxError,
365 )
366 }
367 ref_val => {
368 let is_complement = ref_val < 0;
369 let node = &NODES[(ref_val.unsigned_abs() as usize) - 1];
370 let condition_result = match node.condition_index {
371 0 => endpoint.is_some(),
372 1 => region.is_some(),
373 2 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
374 let partition_result_ssa_2 = &mut context.partition_result_ssa_2;
375 let partition_resolver = &self.partition_resolver;
376 {
377 *partition_result_ssa_2 = partition_resolver
378 .resolve_partition(if let Some(param) = region { param } else { return false }, _diagnostic_collector)
379 .map(|inner| inner.into());
380 partition_result_ssa_2.is_some()
381 }
382 })(&mut _diagnostic_collector),
383 3 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
384 let partition_result_ssa_1 = &mut context.partition_result_ssa_1;
385 let partition_resolver = &self.partition_resolver;
386 {
387 *partition_result_ssa_1 = partition_resolver
388 .resolve_partition("us-west-2", _diagnostic_collector)
389 .map(|inner| inner.into());
390 partition_result_ssa_1.is_some()
391 }
392 })(&mut _diagnostic_collector),
393 4 => (use_fips) == (&true),
394 5 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
395 let partition_result_ssa_1 = &context.partition_result_ssa_1;
396 let partition_resolver = &self.partition_resolver;
397 (if let Some(inner) = partition_result_ssa_1 {
398 inner.supports_fips()
399 } else {
400 return false;
401 }) == (true)
402 })(&mut _diagnostic_collector),
403 6 => (|_diagnostic_collector: &mut crate::endpoint_lib::diagnostic::DiagnosticCollector| -> bool {
404 let partition_result_ssa_2 = &context.partition_result_ssa_2;
405 let partition_resolver = &self.partition_resolver;
406 (if let Some(inner) = partition_result_ssa_2 {
407 inner.supports_fips()
408 } else {
409 return false;
410 }) == (true)
411 })(&mut _diagnostic_collector),
412 _ => unreachable!("Invalid condition index"),
413 };
414 current_ref = if is_complement ^ condition_result { node.high_ref } else { node.low_ref };
415 }
416 }
417 }
418 }
419}
420
421impl crate::config::endpoint::ResolveEndpoint for DefaultResolver {
422 fn resolve_endpoint<'a>(&'a self, params: &'a crate::config::endpoint::Params) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a> {
423 let cached = self.endpoint_cache.load();
425 if let Some((cached_params, cached_endpoint)) = cached.as_ref() {
426 if cached_params == params {
427 return ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(::std::result::Result::Ok(cached_endpoint.clone()));
428 }
429 }
430 drop(cached);
431 let result = self.resolve_endpoint(params);
432 if let ::std::result::Result::Ok(ref endpoint) = result {
433 self.endpoint_cache.store(::std::sync::Arc::new(Some((params.clone(), endpoint.clone()))));
434 }
435 ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(result)
436 }
437}
438const NODES: [crate::endpoint_lib::bdd_interpreter::BddNode; 9] = [
439 crate::endpoint_lib::bdd_interpreter::BddNode {
440 condition_index: -1,
441 high_ref: 1,
442 low_ref: -1,
443 },
444 crate::endpoint_lib::bdd_interpreter::BddNode {
445 condition_index: 0,
446 high_ref: 100000001,
447 low_ref: 3,
448 },
449 crate::endpoint_lib::bdd_interpreter::BddNode {
450 condition_index: 1,
451 high_ref: 7,
452 low_ref: 4,
453 },
454 crate::endpoint_lib::bdd_interpreter::BddNode {
455 condition_index: 3,
456 high_ref: 5,
457 low_ref: 100000000,
458 },
459 crate::endpoint_lib::bdd_interpreter::BddNode {
460 condition_index: 4,
461 high_ref: 6,
462 low_ref: 100000004,
463 },
464 crate::endpoint_lib::bdd_interpreter::BddNode {
465 condition_index: 5,
466 high_ref: 100000003,
467 low_ref: 100000002,
468 },
469 crate::endpoint_lib::bdd_interpreter::BddNode {
470 condition_index: 2,
471 high_ref: 8,
472 low_ref: 100000000,
473 },
474 crate::endpoint_lib::bdd_interpreter::BddNode {
475 condition_index: 4,
476 high_ref: 9,
477 low_ref: 100000006,
478 },
479 crate::endpoint_lib::bdd_interpreter::BddNode {
480 condition_index: 6,
481 high_ref: 100000005,
482 low_ref: 100000002,
483 },
484];
485#[derive(Default)]
488#[allow(unused_lifetimes)]
489pub(crate) struct ConditionContext<'a> {
490 pub(crate) partition_result_ssa_2: Option<crate::endpoint_lib::partition::Partition<'a>>,
491 pub(crate) partition_result_ssa_1: Option<crate::endpoint_lib::partition::Partition<'a>>,
492 phantom: std::marker::PhantomData<&'a ()>,
494}
495
496#[non_exhaustive]
497#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
498pub struct Params {
500 pub(crate) use_fips: bool,
502 pub(crate) region: ::std::option::Option<::std::string::String>,
504 pub(crate) endpoint: ::std::option::Option<::std::string::String>,
506}
507impl Params {
508 pub fn builder() -> crate::config::endpoint::ParamsBuilder {
510 crate::config::endpoint::ParamsBuilder::default()
511 }
512 pub fn use_fips(&self) -> ::std::option::Option<bool> {
514 Some(self.use_fips)
515 }
516 pub fn region(&self) -> ::std::option::Option<&str> {
518 self.region.as_deref()
519 }
520 pub fn endpoint(&self) -> ::std::option::Option<&str> {
522 self.endpoint.as_deref()
523 }
524}
525
526#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug)]
528pub struct ParamsBuilder {
529 use_fips: ::std::option::Option<bool>,
530 region: ::std::option::Option<::std::string::String>,
531 endpoint: ::std::option::Option<::std::string::String>,
532}
533impl ParamsBuilder {
534 pub fn build(self) -> ::std::result::Result<crate::config::endpoint::Params, crate::config::endpoint::InvalidParams> {
536 if let Some(region) = &self.region {
537 if !crate::endpoint_lib::host::is_valid_host_label(
538 region.as_ref() as &str,
539 true,
540 &mut crate::endpoint_lib::diagnostic::DiagnosticCollector::new(),
541 ) {
542 return Err(crate::config::endpoint::InvalidParams::invalid_value(
543 "region",
544 "must be a valid host label",
545 ));
546 }
547 };
548 Ok(
549 #[allow(clippy::unnecessary_lazy_evaluations)]
550 crate::config::endpoint::Params {
551 use_fips: self
552 .use_fips
553 .or_else(|| Some(false))
554 .ok_or_else(|| crate::config::endpoint::InvalidParams::missing("use_fips"))?,
555 region: self.region,
556 endpoint: self.endpoint,
557 },
558 )
559 }
560 pub fn use_fips(mut self, value: impl Into<bool>) -> Self {
565 self.use_fips = Some(value.into());
566 self
567 }
568
569 pub fn set_use_fips(mut self, param: Option<bool>) -> Self {
574 self.use_fips = param;
575 self
576 }
577 pub fn region(mut self, value: impl Into<::std::string::String>) -> Self {
581 self.region = Some(value.into());
582 self
583 }
584
585 pub fn set_region(mut self, param: Option<::std::string::String>) -> Self {
589 self.region = param;
590 self
591 }
592 pub fn endpoint(mut self, value: impl Into<::std::string::String>) -> Self {
596 self.endpoint = Some(value.into());
597 self
598 }
599
600 pub fn set_endpoint(mut self, param: Option<::std::string::String>) -> Self {
604 self.endpoint = param;
605 self
606 }
607}
608
609#[derive(Debug)]
611pub struct InvalidParams {
612 field: std::borrow::Cow<'static, str>,
613 kind: InvalidParamsErrorKind,
614}
615
616#[derive(Debug)]
618enum InvalidParamsErrorKind {
619 MissingField,
620 InvalidValue { message: &'static str },
621}
622
623impl InvalidParams {
624 #[allow(dead_code)]
625 fn missing(field: &'static str) -> Self {
626 Self {
627 field: field.into(),
628 kind: InvalidParamsErrorKind::MissingField,
629 }
630 }
631
632 #[allow(dead_code)]
633 fn invalid_value(field: &'static str, message: &'static str) -> Self {
634 Self {
635 field: field.into(),
636 kind: InvalidParamsErrorKind::InvalidValue { message },
637 }
638 }
639}
640
641impl std::fmt::Display for InvalidParams {
642 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
643 match self.kind {
644 InvalidParamsErrorKind::MissingField => write!(f, "a required field was missing: `{}`", self.field),
645 InvalidParamsErrorKind::InvalidValue { message } => write!(f, "invalid value for field: `{}` - {}", self.field, message),
646 }
647 }
648}
649
650impl std::error::Error for InvalidParams {}