gitlab/api/projects/deployments/
deployments.rs1use chrono::{DateTime, Utc};
8use derive_builder::Builder;
9
10use crate::api::common::{NameOrId, SortOrder};
11use crate::api::endpoint_prelude::*;
12use crate::api::projects::deployments::DeploymentStatus;
13use crate::api::ParamValue;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum DeploymentOrderBy {
19 Id,
21 Iid,
23 CreatedAt,
25 UpdatedAt,
27 FinishedAt,
29 Ref,
31}
32
33impl DeploymentOrderBy {
34 pub(crate) fn as_str(self) -> &'static str {
36 match self {
37 Self::Id => "id",
38 Self::Iid => "iid",
39 Self::CreatedAt => "created_at",
40 Self::UpdatedAt => "updated_at",
41 Self::FinishedAt => "finished_at",
42 Self::Ref => "ref",
43 }
44 }
45}
46
47impl ParamValue<'static> for DeploymentOrderBy {
48 fn as_value(&self) -> Cow<'static, str> {
49 self.as_str().into()
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55#[non_exhaustive]
56pub enum DeploymentStatusFilter {
57 Created,
59 Running,
61 Success,
63 Failed,
65 Canceled,
67 Blocked,
69}
70
71impl DeploymentStatusFilter {
72 pub(crate) fn as_str(self) -> &'static str {
74 match self {
75 Self::Created => "created",
76 Self::Running => "running",
77 Self::Success => "success",
78 Self::Failed => "failed",
79 Self::Canceled => "canceled",
80 Self::Blocked => "blocked",
81 }
82 }
83}
84
85impl From<DeploymentStatus> for DeploymentStatusFilter {
86 fn from(status: DeploymentStatus) -> Self {
87 match status {
88 DeploymentStatus::Running => Self::Running,
89 DeploymentStatus::Success => Self::Success,
90 DeploymentStatus::Failed => Self::Failed,
91 DeploymentStatus::Canceled => Self::Canceled,
92 }
93 }
94}
95
96impl ParamValue<'static> for DeploymentStatusFilter {
97 fn as_value(&self) -> Cow<'static, str> {
98 self.as_str().into()
99 }
100}
101
102#[derive(Debug, Builder, Clone)]
104#[builder(setter(strip_option))]
105pub struct Deployments<'a> {
106 #[builder(setter(into))]
108 project: NameOrId<'a>,
109
110 #[builder(default)]
112 order_by: Option<DeploymentOrderBy>,
113 #[builder(default)]
115 sort: Option<SortOrder>,
116 #[builder(default)]
118 updated_after: Option<DateTime<Utc>>,
119 #[builder(default)]
121 updated_before: Option<DateTime<Utc>>,
122 #[builder(default)]
124 finished_after: Option<DateTime<Utc>>,
125 #[builder(default)]
127 finished_before: Option<DateTime<Utc>>,
128 #[builder(setter(into), default)]
130 environment: Option<Cow<'a, str>>,
131 #[builder(setter(into), default)]
133 status: Option<DeploymentStatusFilter>,
134}
135
136impl<'a> Deployments<'a> {
137 pub fn builder() -> DeploymentsBuilder<'a> {
139 DeploymentsBuilder::default()
140 }
141}
142
143impl Endpoint for Deployments<'_> {
144 fn method(&self) -> Method {
145 Method::GET
146 }
147
148 fn endpoint(&self) -> Cow<'static, str> {
149 format!("projects/{}/deployments", self.project).into()
150 }
151
152 fn parameters(&self) -> QueryParams {
153 let mut params = QueryParams::default();
154
155 params
156 .push_opt("order_by", self.order_by)
157 .push_opt("sort", self.sort)
158 .push_opt("updated_after", self.updated_after)
159 .push_opt("updated_before", self.updated_before)
160 .push_opt("finished_after", self.finished_after)
161 .push_opt("finished_before", self.finished_before)
162 .push_opt("environment", self.environment.as_ref())
163 .push_opt("status", self.status);
164
165 params
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use chrono::{TimeZone, Utc};
172
173 use crate::api::common::SortOrder;
174 use crate::api::projects::deployments::{
175 DeploymentOrderBy, DeploymentStatus, DeploymentStatusFilter, Deployments,
176 DeploymentsBuilderError,
177 };
178 use crate::api::{self, Query};
179 use crate::test::client::{ExpectedUrl, SingleTestClient};
180
181 #[test]
182 fn deployment_order_by_as_str() {
183 let items = &[
184 (DeploymentOrderBy::Id, "id"),
185 (DeploymentOrderBy::Iid, "iid"),
186 (DeploymentOrderBy::CreatedAt, "created_at"),
187 (DeploymentOrderBy::UpdatedAt, "updated_at"),
188 (DeploymentOrderBy::FinishedAt, "finished_at"),
189 (DeploymentOrderBy::Ref, "ref"),
190 ];
191
192 for (i, s) in items {
193 assert_eq!(i.as_str(), *s);
194 }
195 }
196
197 #[test]
198 fn deployment_status_filter_as_str() {
199 let items = &[
200 (DeploymentStatusFilter::Created, "created"),
201 (DeploymentStatusFilter::Running, "running"),
202 (DeploymentStatusFilter::Success, "success"),
203 (DeploymentStatusFilter::Failed, "failed"),
204 (DeploymentStatusFilter::Canceled, "canceled"),
205 (DeploymentStatusFilter::Blocked, "blocked"),
206 ];
207
208 for (i, s) in items {
209 assert_eq!(i.as_str(), *s);
210 }
211 }
212
213 #[test]
214 fn deployment_status_filter_from_deployment_status() {
215 let items = &[
216 (DeploymentStatus::Running, DeploymentStatusFilter::Running),
217 (DeploymentStatus::Success, DeploymentStatusFilter::Success),
218 (DeploymentStatus::Failed, DeploymentStatusFilter::Failed),
219 (DeploymentStatus::Canceled, DeploymentStatusFilter::Canceled),
220 ];
221
222 for (i, f) in items {
223 assert_eq!(DeploymentStatusFilter::from(*i), *f);
224 }
225 }
226
227 #[test]
228 fn project_is_needed() {
229 let err = Deployments::builder().build().unwrap_err();
230 crate::test::assert_missing_field!(err, DeploymentsBuilderError, "project");
231 }
232
233 #[test]
234 fn project_is_sufficient() {
235 Deployments::builder().project(1).build().unwrap();
236 }
237
238 #[test]
239 fn endpoint() {
240 let endpoint = ExpectedUrl::builder()
241 .endpoint("projects/simple%2Fproject/deployments")
242 .build()
243 .unwrap();
244 let client = SingleTestClient::new_raw(endpoint, "");
245
246 let endpoint = Deployments::builder()
247 .project("simple/project")
248 .build()
249 .unwrap();
250 api::ignore(endpoint).query(&client).unwrap();
251 }
252
253 #[test]
254 fn endpoint_order_by() {
255 let endpoint = ExpectedUrl::builder()
256 .endpoint("projects/1/deployments")
257 .add_query_params(&[("order_by", "ref")])
258 .build()
259 .unwrap();
260 let client = SingleTestClient::new_raw(endpoint, "");
261
262 let endpoint = Deployments::builder()
263 .project(1)
264 .order_by(DeploymentOrderBy::Ref)
265 .build()
266 .unwrap();
267 api::ignore(endpoint).query(&client).unwrap();
268 }
269
270 #[test]
271 fn endpoint_sort() {
272 let endpoint = ExpectedUrl::builder()
273 .endpoint("projects/1/deployments")
274 .add_query_params(&[("sort", "desc")])
275 .build()
276 .unwrap();
277 let client = SingleTestClient::new_raw(endpoint, "");
278
279 let endpoint = Deployments::builder()
280 .project(1)
281 .sort(SortOrder::Descending)
282 .build()
283 .unwrap();
284 api::ignore(endpoint).query(&client).unwrap();
285 }
286
287 #[test]
288 fn endpoint_updated_after() {
289 let endpoint = ExpectedUrl::builder()
290 .endpoint("projects/1/deployments")
291 .add_query_params(&[("updated_after", "2024-01-01T00:00:00Z")])
292 .build()
293 .unwrap();
294 let client = SingleTestClient::new_raw(endpoint, "");
295
296 let endpoint = Deployments::builder()
297 .project(1)
298 .updated_after(Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap())
299 .build()
300 .unwrap();
301 api::ignore(endpoint).query(&client).unwrap();
302 }
303
304 #[test]
305 fn endpoint_updated_before() {
306 let endpoint = ExpectedUrl::builder()
307 .endpoint("projects/1/deployments")
308 .add_query_params(&[("updated_before", "2024-01-01T00:00:00Z")])
309 .build()
310 .unwrap();
311 let client = SingleTestClient::new_raw(endpoint, "");
312
313 let endpoint = Deployments::builder()
314 .project(1)
315 .updated_before(Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap())
316 .build()
317 .unwrap();
318 api::ignore(endpoint).query(&client).unwrap();
319 }
320
321 #[test]
322 fn endpoint_finished_after() {
323 let endpoint = ExpectedUrl::builder()
324 .endpoint("projects/1/deployments")
325 .add_query_params(&[("finished_after", "2024-01-01T00:00:00Z")])
326 .build()
327 .unwrap();
328 let client = SingleTestClient::new_raw(endpoint, "");
329
330 let endpoint = Deployments::builder()
331 .project(1)
332 .finished_after(Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap())
333 .build()
334 .unwrap();
335 api::ignore(endpoint).query(&client).unwrap();
336 }
337
338 #[test]
339 fn endpoint_finished_before() {
340 let endpoint = ExpectedUrl::builder()
341 .endpoint("projects/1/deployments")
342 .add_query_params(&[("finished_before", "2024-01-01T00:00:00Z")])
343 .build()
344 .unwrap();
345 let client = SingleTestClient::new_raw(endpoint, "");
346
347 let endpoint = Deployments::builder()
348 .project(1)
349 .finished_before(Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap())
350 .build()
351 .unwrap();
352 api::ignore(endpoint).query(&client).unwrap();
353 }
354
355 #[test]
356 fn endpoint_environment() {
357 let endpoint = ExpectedUrl::builder()
358 .endpoint("projects/1/deployments")
359 .add_query_params(&[("environment", "env")])
360 .build()
361 .unwrap();
362 let client = SingleTestClient::new_raw(endpoint, "");
363
364 let endpoint = Deployments::builder()
365 .project(1)
366 .environment("env")
367 .build()
368 .unwrap();
369 api::ignore(endpoint).query(&client).unwrap();
370 }
371
372 #[test]
373 fn endpoint_status() {
374 let endpoint = ExpectedUrl::builder()
375 .endpoint("projects/1/deployments")
376 .add_query_params(&[("status", "failed")])
377 .build()
378 .unwrap();
379 let client = SingleTestClient::new_raw(endpoint, "");
380
381 let endpoint = Deployments::builder()
382 .project(1)
383 .status(DeploymentStatus::Failed)
384 .build()
385 .unwrap();
386 api::ignore(endpoint).query(&client).unwrap();
387 }
388}