Skip to main content

openstack_sdk_identity/v3/project/
set.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5//     http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12//
13// SPDX-License-Identifier: Apache-2.0
14//
15// WARNING: This file is automatically generated from OpenAPI schema using
16// `openstack-codegenerator`.
17
18//! Updates a project.
19//!
20//! Relationship:
21//! `https://docs.openstack.org/api/openstack-identity/3/rel/project`
22//!
23use 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/// The resource options for the project. Available resource options are
33/// `immutable`.
34#[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/// A `project` object
43#[derive(Builder, Debug, Deserialize, Clone, Serialize)]
44#[builder(setter(strip_option))]
45pub struct Project<'a> {
46    /// The description of the project.
47    #[serde(skip_serializing_if = "Option::is_none")]
48    #[builder(default, setter(into))]
49    pub(crate) description: Option<Option<Cow<'a, str>>>,
50
51    /// If set to `true`, project is enabled. If set to `false`, project is
52    /// disabled.
53    #[serde(skip_serializing_if = "Option::is_none")]
54    #[builder(default, setter(into))]
55    pub(crate) enabled: Option<bool>,
56
57    /// The name of the project, which must be unique within the owning domain.
58    /// A project can have the same name as its domain.
59    #[serde(skip_serializing_if = "Option::is_none")]
60    #[builder(default, setter(into))]
61    pub(crate) name: Option<Cow<'a, str>>,
62
63    /// The resource options for the project. Available resource options are
64    /// `immutable`.
65    #[serde(skip_serializing_if = "Option::is_none")]
66    #[builder(default, setter(into))]
67    pub(crate) options: Option<Options>,
68
69    /// A list of simple strings assigned to a project. Tags can be used to
70    /// classify projects into groups.
71    #[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    /// A `project` object
80    #[builder(setter(into))]
81    pub(crate) project: Project<'a>,
82
83    /// project_id parameter for /v3/projects/{project_id} API
84    #[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    /// Create a builder for the endpoint.
92    pub fn builder() -> RequestBuilder<'a> {
93        RequestBuilder::default()
94    }
95}
96
97impl<'a> RequestBuilder<'a> {
98    /// Add a single header to the Project.
99    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    /// Add multiple headers.
112    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    /// Returns headers to be set into the request
155    fn request_headers(&self) -> Option<&HeaderMap> {
156        self._headers.as_ref()
157    }
158
159    /// Returns required API version
160    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}