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