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