openstack_sdk_identity/v3/credential/
set.rs1use derive_builder::Builder;
24use http::{HeaderMap, HeaderName, HeaderValue};
25
26use openstack_sdk_core::api::rest_endpoint_prelude::*;
27
28use serde::Deserialize;
29use serde::Serialize;
30use serde_json::Value;
31use std::borrow::Cow;
32use std::collections::BTreeMap;
33
34#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
36#[builder(setter(strip_option))]
37pub struct Credential<'a> {
38 #[serde(skip_serializing_if = "Option::is_none")]
40 #[builder(default, setter(into))]
41 pub(crate) blob: Option<Cow<'a, str>>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
45 #[builder(default, setter(into))]
46 pub(crate) project_id: Option<Option<Cow<'a, str>>>,
47
48 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
51 #[builder(default, setter(into))]
52 pub(crate) _type: Option<Cow<'a, str>>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 #[builder(default, setter(into))]
57 pub(crate) user_id: Option<Cow<'a, str>>,
58
59 #[builder(setter(name = "_properties"), default, private)]
60 #[serde(flatten)]
61 _properties: BTreeMap<Cow<'a, str>, Value>,
62}
63
64impl<'a> CredentialBuilder<'a> {
65 pub fn properties<I, K, V>(&mut self, iter: I) -> &mut Self
66 where
67 I: Iterator<Item = (K, V)>,
68 K: Into<Cow<'a, str>>,
69 V: Into<Value>,
70 {
71 self._properties
72 .get_or_insert_with(BTreeMap::new)
73 .extend(iter.map(|(k, v)| (k.into(), v.into())));
74 self
75 }
76}
77
78#[derive(Builder, Debug, Clone)]
79#[builder(setter(strip_option))]
80pub struct Request<'a> {
81 #[builder(setter(into))]
83 pub(crate) credential: Credential<'a>,
84
85 #[builder(default, setter(into))]
87 id: Cow<'a, str>,
88
89 #[builder(setter(name = "_headers"), default, private)]
90 _headers: Option<HeaderMap>,
91}
92impl<'a> Request<'a> {
93 pub fn builder() -> RequestBuilder<'a> {
95 RequestBuilder::default()
96 }
97}
98
99impl<'a> RequestBuilder<'a> {
100 pub fn header<K, V>(&mut self, header_name: K, header_value: V) -> &mut Self
102 where
103 K: Into<HeaderName>,
104 V: Into<HeaderValue>,
105 {
106 self._headers
107 .get_or_insert(None)
108 .get_or_insert_with(HeaderMap::new)
109 .insert(header_name.into(), header_value.into());
110 self
111 }
112
113 pub fn headers<I, T>(&mut self, iter: I) -> &mut Self
115 where
116 I: Iterator<Item = T>,
117 T: Into<(Option<HeaderName>, HeaderValue)>,
118 {
119 self._headers
120 .get_or_insert(None)
121 .get_or_insert_with(HeaderMap::new)
122 .extend(iter.map(Into::into));
123 self
124 }
125}
126
127impl RestEndpoint for Request<'_> {
128 fn method(&self) -> http::Method {
129 http::Method::PATCH
130 }
131
132 fn endpoint(&self) -> Cow<'static, str> {
133 format!("credentials/{id}", id = self.id.as_ref(),).into()
134 }
135
136 fn parameters(&self) -> QueryParams<'_> {
137 QueryParams::default()
138 }
139
140 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
141 let mut params = JsonBodyParams::default();
142
143 params.push("credential", serde_json::to_value(&self.credential)?);
144
145 params.into_body()
146 }
147
148 fn service_type(&self) -> ServiceType {
149 ServiceType::Identity
150 }
151
152 fn response_key(&self) -> Option<Cow<'static, str>> {
153 Some("credential".into())
154 }
155
156 fn request_headers(&self) -> Option<&HeaderMap> {
158 self._headers.as_ref()
159 }
160
161 fn api_version(&self) -> Option<ApiVersion> {
163 Some(ApiVersion::new(3, 0))
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170 use http::{HeaderName, HeaderValue};
171 use httpmock::MockServer;
172 #[cfg(feature = "sync")]
173 use openstack_sdk_core::api::Query;
174 use openstack_sdk_core::test::client::FakeOpenStackClient;
175 use openstack_sdk_core::types::ServiceType;
176 use serde_json::json;
177
178 #[test]
179 fn test_service_type() {
180 assert_eq!(
181 Request::builder()
182 .credential(CredentialBuilder::default().build().unwrap())
183 .build()
184 .unwrap()
185 .service_type(),
186 ServiceType::Identity
187 );
188 }
189
190 #[test]
191 fn test_response_key() {
192 assert_eq!(
193 Request::builder()
194 .credential(CredentialBuilder::default().build().unwrap())
195 .build()
196 .unwrap()
197 .response_key()
198 .unwrap(),
199 "credential"
200 );
201 }
202
203 #[cfg(feature = "sync")]
204 #[test]
205 fn endpoint() {
206 let server = MockServer::start();
207 let client = FakeOpenStackClient::new(server.base_url());
208 let mock = server.mock(|when, then| {
209 when.method(httpmock::Method::PATCH)
210 .path(format!("/credentials/{id}", id = "id",));
211
212 then.status(200)
213 .header("content-type", "application/json")
214 .json_body(json!({ "credential": {} }));
215 });
216
217 let endpoint = Request::builder()
218 .id("id")
219 .credential(CredentialBuilder::default().build().unwrap())
220 .build()
221 .unwrap();
222 let _: serde_json::Value = endpoint.query(&client).unwrap();
223 mock.assert();
224 }
225
226 #[cfg(feature = "sync")]
227 #[test]
228 fn endpoint_headers() {
229 let server = MockServer::start();
230 let client = FakeOpenStackClient::new(server.base_url());
231 let mock = server.mock(|when, then| {
232 when.method(httpmock::Method::PATCH)
233 .path(format!("/credentials/{id}", id = "id",))
234 .header("foo", "bar")
235 .header("not_foo", "not_bar");
236 then.status(200)
237 .header("content-type", "application/json")
238 .json_body(json!({ "credential": {} }));
239 });
240
241 let endpoint = Request::builder()
242 .id("id")
243 .credential(CredentialBuilder::default().build().unwrap())
244 .headers(
245 [(
246 Some(HeaderName::from_static("foo")),
247 HeaderValue::from_static("bar"),
248 )]
249 .into_iter(),
250 )
251 .header(
252 HeaderName::from_static("not_foo"),
253 HeaderValue::from_static("not_bar"),
254 )
255 .build()
256 .unwrap();
257 let _: serde_json::Value = endpoint.query(&client).unwrap();
258 mock.assert();
259 }
260}