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