aws_sdk_agentregistrycontrol/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 .region("us-west-2".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://agent-registry-control.us-west-2.api.aws");
42 assert_eq!(
43 endpoint,
44 ::aws_smithy_types::endpoint::Endpoint::builder()
45 .url("https://agent-registry-control.us-west-2.api.aws")
46 .build()
47 );
48 }
49
50 #[test]
52 fn test_2() {
53 let params = crate::config::endpoint::Params::builder()
54 .region("us-east-1".to_string())
55 .build()
56 .expect("invalid params");
57 let resolver = crate::config::endpoint::DefaultResolver::new();
58 let endpoint = resolver.resolve_endpoint(¶ms);
59 let endpoint = endpoint.expect("Expected valid endpoint: https://agent-registry-control.us-east-1.api.aws");
60 assert_eq!(
61 endpoint,
62 ::aws_smithy_types::endpoint::Endpoint::builder()
63 .url("https://agent-registry-control.us-east-1.api.aws")
64 .build()
65 );
66 }
67
68 #[test]
70 fn test_3() {
71 let params = crate::config::endpoint::Params::builder()
72 .region("us-west-2".to_string())
73 .endpoint("https://custom.example.aws.dev".to_string())
74 .build()
75 .expect("invalid params");
76 let resolver = crate::config::endpoint::DefaultResolver::new();
77 let endpoint = resolver.resolve_endpoint(¶ms);
78 let endpoint = endpoint.expect("Expected valid endpoint: https://custom.example.aws.dev");
79 assert_eq!(
80 endpoint,
81 ::aws_smithy_types::endpoint::Endpoint::builder()
82 .url("https://custom.example.aws.dev")
83 .build()
84 );
85 }
86}
87
88pub trait ResolveEndpoint: ::std::marker::Send + ::std::marker::Sync + ::std::fmt::Debug {
90 fn resolve_endpoint<'a>(&'a self, params: &'a crate::config::endpoint::Params) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a>;
92
93 fn into_shared_resolver(self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver
97 where
98 Self: Sized + 'static,
99 {
100 ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver::new(DowncastParams(self))
101 }
102}
103
104#[derive(Debug)]
105struct DowncastParams<T>(T);
106impl<T> ::aws_smithy_runtime_api::client::endpoint::ResolveEndpoint for DowncastParams<T>
107where
108 T: ResolveEndpoint,
109{
110 fn resolve_endpoint<'a>(
111 &'a self,
112 params: &'a ::aws_smithy_runtime_api::client::endpoint::EndpointResolverParams,
113 ) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a> {
114 let ep = match params.get::<crate::config::endpoint::Params>() {
115 Some(params) => self.0.resolve_endpoint(params),
116 None => ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(Err("params of expected type was not present".into())),
117 };
118 ep
119 }
120}
121
122#[derive(Debug)]
123pub struct DefaultResolver {
125 endpoint_cache: ::arc_swap::ArcSwap<::std::option::Option<(Params, ::aws_smithy_types::endpoint::Endpoint)>>,
126}
127
128impl Default for DefaultResolver {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134impl DefaultResolver {
135 pub fn new() -> Self {
137 Self {
138 endpoint_cache: ::arc_swap::ArcSwap::from_pointee(None),
139 }
140 }
141
142 #[allow(
143 unused_variables,
144 unused_parens,
145 clippy::double_parens,
146 clippy::useless_conversion,
147 clippy::bool_comparison,
148 clippy::comparison_to_empty,
149 clippy::needless_borrow,
150 clippy::useless_asref,
151 clippy::redundant_closure_call,
152 clippy::clone_on_copy,
153 clippy::single_char_add_str
154 )]
155 fn resolve_endpoint<'a>(
156 &'a self,
157 params: &'a crate::config::endpoint::Params,
158 ) -> ::std::result::Result<::aws_smithy_types::endpoint::Endpoint, ::aws_smithy_runtime_api::box_error::BoxError> {
159 let mut _diagnostic_collector = crate::endpoint_lib::diagnostic::DiagnosticCollector::new();
160 #[allow(unused_mut)]
161 let mut context = ConditionContext::default();
162
163 let region = ¶ms.region;
165 let endpoint = ¶ms.endpoint;
166
167 let mut current_ref: i32 = 2;
168 loop {
169 match current_ref {
170 ref_val if ref_val >= 100_000_000 => {
171 return match (ref_val - 100_000_000) as usize {
172 0 => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("No endpoint rule matched")) as ::aws_smithy_runtime_api::box_error::BoxError),
1731 => {
174 let endpoint = params.endpoint.as_deref().unwrap_or_default();
175 ::std::result::Result::Ok(::aws_smithy_types::endpoint::Endpoint::builder().url(endpoint.to_owned())
176.build())
177 },
1782 => {
179 let region = params.region.as_deref().unwrap_or_default();
180 ::std::result::Result::Ok(::aws_smithy_types::endpoint::Endpoint::builder().url({ let mut out = String::new();
181out.push_str("https://agent-registry-control.");
182#[allow(clippy::needless_borrow)]
183out.push_str(®ion.as_ref());
184out.push_str(".api.aws");
185out })
186.build())
187 },
1883 => {
189
190 ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("Unable to resolve an Agent Registry Control endpoint: Region was not set and no explicit Endpoint override was provided."
191.to_string())) as ::aws_smithy_runtime_api::box_error::BoxError)
192 },
193 _ => ::std::result::Result::Err(Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("No endpoint rule matched")) as ::aws_smithy_runtime_api::box_error::BoxError),
194 };
195 }
196 1 | -1 => {
197 return ::std::result::Result::Err(
198 Box::new(::aws_smithy_http::endpoint::ResolveEndpointError::message("No endpoint rule matched"))
199 as ::aws_smithy_runtime_api::box_error::BoxError,
200 )
201 }
202 ref_val => {
203 let is_complement = ref_val < 0;
204 let node = &NODES[(ref_val.unsigned_abs() as usize) - 1];
205 let condition_result = match node.condition_index {
206 0 => endpoint.is_some(),
207 1 => region.is_some(),
208 _ => unreachable!("Invalid condition index"),
209 };
210 current_ref = if is_complement ^ condition_result { node.high_ref } else { node.low_ref };
211 }
212 }
213 }
214 }
215}
216
217impl crate::config::endpoint::ResolveEndpoint for DefaultResolver {
218 fn resolve_endpoint<'a>(&'a self, params: &'a crate::config::endpoint::Params) -> ::aws_smithy_runtime_api::client::endpoint::EndpointFuture<'a> {
219 let cached = self.endpoint_cache.load();
221 if let Some((cached_params, cached_endpoint)) = cached.as_ref() {
222 if cached_params == params {
223 return ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(::std::result::Result::Ok(cached_endpoint.clone()));
224 }
225 }
226 drop(cached);
227 let result = self.resolve_endpoint(params);
228 if let ::std::result::Result::Ok(ref endpoint) = result {
229 self.endpoint_cache.store(::std::sync::Arc::new(Some((params.clone(), endpoint.clone()))));
230 }
231 ::aws_smithy_runtime_api::client::endpoint::EndpointFuture::ready(result)
232 }
233}
234const NODES: [crate::endpoint_lib::bdd_interpreter::BddNode; 3] = [
235 crate::endpoint_lib::bdd_interpreter::BddNode {
236 condition_index: -1,
237 high_ref: 1,
238 low_ref: -1,
239 },
240 crate::endpoint_lib::bdd_interpreter::BddNode {
241 condition_index: 0,
242 high_ref: 100000001,
243 low_ref: 3,
244 },
245 crate::endpoint_lib::bdd_interpreter::BddNode {
246 condition_index: 1,
247 high_ref: 100000002,
248 low_ref: 100000003,
249 },
250];
251#[derive(Default)]
254#[allow(unused_lifetimes)]
255pub(crate) struct ConditionContext<'a> {
256 phantom: std::marker::PhantomData<&'a ()>,
258}
259
260#[non_exhaustive]
261#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
262pub struct Params {
264 pub(crate) region: ::std::option::Option<::std::string::String>,
266 pub(crate) endpoint: ::std::option::Option<::std::string::String>,
268}
269impl Params {
270 pub fn builder() -> crate::config::endpoint::ParamsBuilder {
272 crate::config::endpoint::ParamsBuilder::default()
273 }
274 pub fn region(&self) -> ::std::option::Option<&str> {
276 self.region.as_deref()
277 }
278 pub fn endpoint(&self) -> ::std::option::Option<&str> {
280 self.endpoint.as_deref()
281 }
282}
283
284#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug)]
286pub struct ParamsBuilder {
287 region: ::std::option::Option<::std::string::String>,
288 endpoint: ::std::option::Option<::std::string::String>,
289}
290impl ParamsBuilder {
291 pub fn build(self) -> ::std::result::Result<crate::config::endpoint::Params, crate::config::endpoint::InvalidParams> {
293 if let Some(region) = &self.region {
294 if !crate::endpoint_lib::host::is_valid_host_label(
295 region.as_ref() as &str,
296 true,
297 &mut crate::endpoint_lib::diagnostic::DiagnosticCollector::new(),
298 ) {
299 return Err(crate::config::endpoint::InvalidParams::invalid_value(
300 "region",
301 "must be a valid host label",
302 ));
303 }
304 };
305 Ok(
306 #[allow(clippy::unnecessary_lazy_evaluations)]
307 crate::config::endpoint::Params {
308 region: self.region,
309 endpoint: self.endpoint,
310 },
311 )
312 }
313 pub fn region(mut self, value: impl Into<::std::string::String>) -> Self {
317 self.region = Some(value.into());
318 self
319 }
320
321 pub fn set_region(mut self, param: Option<::std::string::String>) -> Self {
325 self.region = param;
326 self
327 }
328 pub fn endpoint(mut self, value: impl Into<::std::string::String>) -> Self {
332 self.endpoint = Some(value.into());
333 self
334 }
335
336 pub fn set_endpoint(mut self, param: Option<::std::string::String>) -> Self {
340 self.endpoint = param;
341 self
342 }
343}
344
345#[derive(Debug)]
347pub struct InvalidParams {
348 field: std::borrow::Cow<'static, str>,
349 kind: InvalidParamsErrorKind,
350}
351
352#[derive(Debug)]
354enum InvalidParamsErrorKind {
355 MissingField,
356 InvalidValue { message: &'static str },
357}
358
359impl InvalidParams {
360 #[allow(dead_code)]
361 fn missing(field: &'static str) -> Self {
362 Self {
363 field: field.into(),
364 kind: InvalidParamsErrorKind::MissingField,
365 }
366 }
367
368 #[allow(dead_code)]
369 fn invalid_value(field: &'static str, message: &'static str) -> Self {
370 Self {
371 field: field.into(),
372 kind: InvalidParamsErrorKind::InvalidValue { message },
373 }
374 }
375}
376
377impl std::fmt::Display for InvalidParams {
378 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
379 match self.kind {
380 InvalidParamsErrorKind::MissingField => write!(f, "a required field was missing: `{}`", self.field),
381 InvalidParamsErrorKind::InvalidValue { message } => write!(f, "invalid value for field: `{}` - {}", self.field, message),
382 }
383 }
384}
385
386impl std::error::Error for InvalidParams {}