Skip to main content

gitlab/api/projects/releases/
releases.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use derive_builder::Builder;
8
9use crate::api::common::{NameOrId, SortOrder};
10use crate::api::endpoint_prelude::*;
11use crate::api::ParamValue;
12
13/// Keys group results may be ordered by.
14#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
15#[non_exhaustive]
16pub enum ProjectReleaseOrderBy {
17    /// Order by the release date.
18    #[default]
19    ReleasedAt,
20    /// Order by the creation date.
21    CreatedAt,
22}
23
24impl ProjectReleaseOrderBy {
25    /// The ordering as a query parameter.
26    fn as_str(self) -> &'static str {
27        match self {
28            ProjectReleaseOrderBy::ReleasedAt => "released_at",
29            ProjectReleaseOrderBy::CreatedAt => "created_at",
30        }
31    }
32}
33
34impl ParamValue<'static> for ProjectReleaseOrderBy {
35    fn as_value(&self) -> Cow<'static, str> {
36        self.as_str().into()
37    }
38}
39
40/// Query releases of a project.
41#[derive(Debug, Clone, Builder)]
42#[builder(setter(strip_option))]
43pub struct ProjectReleases<'a> {
44    /// The project to query for releases.
45    #[builder(setter(into))]
46    project: NameOrId<'a>,
47
48    /// Whether to include an HTML render of the description or not.
49    #[builder(default)]
50    include_html_description: Option<bool>,
51
52    /// Order results by a given key.
53    #[builder(default)]
54    order_by: Option<ProjectReleaseOrderBy>,
55    /// The sort order for returned results.
56    #[builder(default)]
57    sort: Option<SortOrder>,
58}
59
60impl<'a> ProjectReleases<'a> {
61    /// Create a builder for the endpoint.
62    pub fn builder() -> ProjectReleasesBuilder<'a> {
63        ProjectReleasesBuilder::default()
64    }
65}
66
67impl Endpoint for ProjectReleases<'_> {
68    fn method(&self) -> Method {
69        Method::GET
70    }
71
72    fn endpoint(&self) -> Cow<'static, str> {
73        format!("projects/{}/releases", self.project).into()
74    }
75
76    fn parameters(&self) -> QueryParams<'_> {
77        let mut params = QueryParams::default();
78
79        params
80            .push_opt("include_html_description", self.include_html_description)
81            .push_opt("order_by", self.order_by)
82            .push_opt("sort", self.sort);
83
84        params
85    }
86}
87
88impl Pageable for ProjectReleases<'_> {}
89
90#[cfg(test)]
91mod tests {
92    use crate::api::common::SortOrder;
93    use crate::api::projects::releases::{
94        ProjectReleaseOrderBy, ProjectReleases, ProjectReleasesBuilderError,
95    };
96    use crate::api::{self, Query};
97    use crate::test::client::{ExpectedUrl, SingleTestClient};
98
99    #[test]
100    fn order_by_default() {
101        assert_eq!(
102            ProjectReleaseOrderBy::default(),
103            ProjectReleaseOrderBy::ReleasedAt,
104        );
105    }
106
107    #[test]
108    fn order_by_as_str() {
109        let items = &[
110            (ProjectReleaseOrderBy::ReleasedAt, "released_at"),
111            (ProjectReleaseOrderBy::CreatedAt, "created_at"),
112        ];
113
114        for (i, s) in items {
115            assert_eq!(i.as_str(), *s);
116        }
117    }
118
119    #[test]
120    fn project_is_needed() {
121        let err = ProjectReleases::builder().build().unwrap_err();
122        crate::test::assert_missing_field!(err, ProjectReleasesBuilderError, "project");
123    }
124
125    #[test]
126    fn project_is_sufficient() {
127        ProjectReleases::builder().project(1).build().unwrap();
128    }
129
130    #[test]
131    fn endpoint() {
132        let endpoint = ExpectedUrl::builder()
133            .endpoint("projects/project/releases")
134            .build()
135            .unwrap();
136        let client = SingleTestClient::new_raw(endpoint, "");
137
138        let endpoint = ProjectReleases::builder()
139            .project("project")
140            .build()
141            .unwrap();
142        api::ignore(endpoint).query(&client).unwrap();
143    }
144
145    #[test]
146    fn endpoint_include_html_description() {
147        let endpoint = ExpectedUrl::builder()
148            .endpoint("projects/project/releases")
149            .add_query_params(&[("include_html_description", "false")])
150            .build()
151            .unwrap();
152        let client = SingleTestClient::new_raw(endpoint, "");
153
154        let endpoint = ProjectReleases::builder()
155            .project("project")
156            .include_html_description(false)
157            .build()
158            .unwrap();
159        api::ignore(endpoint).query(&client).unwrap();
160    }
161
162    #[test]
163    fn endpoint_order_by() {
164        let endpoint = ExpectedUrl::builder()
165            .endpoint("projects/project/releases")
166            .add_query_params(&[("order_by", "created_at")])
167            .build()
168            .unwrap();
169        let client = SingleTestClient::new_raw(endpoint, "");
170
171        let endpoint = ProjectReleases::builder()
172            .project("project")
173            .order_by(ProjectReleaseOrderBy::CreatedAt)
174            .build()
175            .unwrap();
176        api::ignore(endpoint).query(&client).unwrap();
177    }
178
179    #[test]
180    fn endpoint_sort() {
181        let endpoint = ExpectedUrl::builder()
182            .endpoint("projects/project/releases")
183            .add_query_params(&[("sort", "asc")])
184            .build()
185            .unwrap();
186        let client = SingleTestClient::new_raw(endpoint, "");
187
188        let endpoint = ProjectReleases::builder()
189            .project("project")
190            .sort(SortOrder::Ascending)
191            .build()
192            .unwrap();
193        api::ignore(endpoint).query(&client).unwrap();
194    }
195}