aws_smithy_types/
endpoint.rs1use crate::config_bag::{Storable, StoreReplace};
8use crate::Document;
9use std::borrow::Cow;
10use std::collections::HashMap;
11
12type MaybeStatic = Cow<'static, str>;
13
14#[derive(Debug, Clone, PartialEq)]
21pub struct EndpointAuthScheme {
22 name: MaybeStatic,
23 properties: Vec<(MaybeStatic, Document)>,
24}
25
26impl EndpointAuthScheme {
27 pub fn with_capacity(name: impl Into<MaybeStatic>, capacity: usize) -> Self {
29 Self {
30 name: name.into(),
31 properties: Vec::with_capacity(capacity),
32 }
33 }
34
35 pub fn name(&self) -> &str {
37 &self.name
38 }
39
40 pub fn put(mut self, key: impl Into<MaybeStatic>, value: impl Into<Document>) -> Self {
42 self.properties.push((key.into(), value.into()));
43 self
44 }
45
46 pub fn get(&self, key: &str) -> Option<&Document> {
48 self.properties
49 .iter()
50 .find(|(k, _)| k.as_ref() == key)
51 .map(|(_, v)| v)
52 }
53
54 pub fn as_document(&self) -> Document {
56 let mut map = HashMap::with_capacity(self.properties.len() + 1);
57 map.insert("name".to_string(), Document::String(self.name.to_string()));
58 for (k, v) in &self.properties {
59 map.insert(k.to_string(), v.clone());
60 }
61 Document::Object(map)
62 }
63}
64
65#[derive(Debug, Clone, PartialEq)]
70pub struct Endpoint {
71 url: MaybeStatic,
72 headers: HashMap<MaybeStatic, Vec<MaybeStatic>>,
73 properties: HashMap<MaybeStatic, Document>,
74 auth_schemes: Vec<EndpointAuthScheme>,
75}
76
77#[allow(unused)]
80impl Endpoint {
81 pub fn url(&self) -> &str {
83 &self.url
84 }
85
86 pub fn headers(&self) -> impl Iterator<Item = (&str, impl Iterator<Item = &str>)> {
88 self.headers
89 .iter()
90 .map(|(k, v)| (k.as_ref(), v.iter().map(|v| v.as_ref())))
91 }
92
93 pub fn properties(&self) -> &HashMap<Cow<'static, str>, Document> {
95 &self.properties
96 }
97
98 pub fn auth_schemes(&self) -> &[EndpointAuthScheme] {
100 &self.auth_schemes
101 }
102
103 pub fn into_builder(self) -> Builder {
105 Builder { endpoint: self }
106 }
107
108 pub fn builder() -> Builder {
110 Builder::new()
111 }
112}
113
114impl Storable for Endpoint {
115 type Storer = StoreReplace<Self>;
116}
117
118#[derive(Debug, Clone)]
119pub struct Builder {
121 endpoint: Endpoint,
122}
123
124#[allow(unused)]
125impl Builder {
126 pub(crate) fn new() -> Self {
127 Self {
128 endpoint: Endpoint {
129 url: Default::default(),
130 headers: HashMap::new(),
131 properties: HashMap::new(),
132 auth_schemes: Vec::new(),
133 },
134 }
135 }
136
137 pub fn url(mut self, url: impl Into<MaybeStatic>) -> Self {
145 self.endpoint.url = url.into();
146 self
147 }
148
149 pub fn header(mut self, name: impl Into<MaybeStatic>, value: impl Into<MaybeStatic>) -> Self {
159 self.endpoint
160 .headers
161 .entry(name.into())
162 .or_default()
163 .push(value.into());
164 self
165 }
166
167 pub fn property(mut self, key: impl Into<MaybeStatic>, value: impl Into<Document>) -> Self {
180 self.endpoint.properties.insert(key.into(), value.into());
181 self
182 }
183
184 pub fn auth_scheme(mut self, auth_scheme: EndpointAuthScheme) -> Self {
186 self.endpoint.auth_schemes.push(auth_scheme);
187 self
188 }
189
190 pub fn build(self) -> Endpoint {
195 assert_ne!(self.endpoint.url(), "", "URL was unset");
196 self.endpoint
197 }
198}
199
200#[cfg(test)]
201mod test {
202 use crate::endpoint::Endpoint;
203 use crate::Document;
204 use std::borrow::Cow;
205 use std::collections::HashMap;
206
207 #[test]
208 fn endpoint_builder() {
209 let endpoint = Endpoint::builder()
210 .url("https://www.amazon.com")
211 .header("x-amz-test", "header-value")
212 .property("custom", Document::Bool(true))
213 .build();
214 assert_eq!(endpoint.url, Cow::Borrowed("https://www.amazon.com"));
215 assert_eq!(
216 endpoint.headers,
217 HashMap::from([(
218 Cow::Borrowed("x-amz-test"),
219 vec![Cow::Borrowed("header-value")]
220 )])
221 );
222 assert_eq!(
223 endpoint.properties,
224 HashMap::from([(Cow::Borrowed("custom"), Document::Bool(true))])
225 );
226
227 assert_eq!(endpoint.url(), "https://www.amazon.com");
228 assert_eq!(
229 endpoint
230 .headers()
231 .map(|(k, v)| (k, v.collect::<Vec<_>>()))
232 .collect::<Vec<_>>(),
233 vec![("x-amz-test", vec!["header-value"])]
234 );
235 }
236
237 #[test]
238 fn borrowed_values() {
239 fn foo(a: &str) {
240 let endpoint = Endpoint::builder().url(a.to_string()).build();
242 assert_eq!(endpoint.url(), a);
243 }
244
245 foo("asdf");
246 }
247}