gitlab/api/projects/packages/
packages.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 crate::api::common::{NameOrId, SortOrder};
8use crate::api::packages::{PackageStatus, PackageType};
9use crate::api::{endpoint_prelude::*, ParamValue};
10use derive_builder::Builder;
11
12/// Sort orderings for packages.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum PackageOrderBy {
16    /// Order by the creation date of the package.
17    CreatedAt,
18    /// Order by the name of the package.
19    Name,
20    /// Order by the version of the package.
21    Version,
22    /// Order by the type of the package.
23    Type,
24}
25
26impl PackageOrderBy {
27    /// The scope as a query parameter.
28    pub(crate) fn as_str(self) -> &'static str {
29        match self {
30            PackageOrderBy::CreatedAt => "created_at",
31            PackageOrderBy::Name => "name",
32            PackageOrderBy::Version => "version",
33            PackageOrderBy::Type => "type",
34        }
35    }
36}
37
38impl ParamValue<'static> for PackageOrderBy {
39    fn as_value(&self) -> Cow<'static, str> {
40        self.as_str().into()
41    }
42}
43
44/// List packages within a project
45#[derive(Debug, Builder, Clone)]
46#[builder(setter(strip_option))]
47pub struct Packages<'a> {
48    /// The project to query for the packages.
49    #[builder(setter(into))]
50    project: NameOrId<'a>,
51
52    /// How to order returned results.
53    #[builder(default)]
54    order_by: Option<PackageOrderBy>,
55
56    /// The sort order of returned packages.
57    #[builder(default)]
58    sort: Option<SortOrder>,
59
60    /// Filter results by package type.
61    #[builder(default)]
62    package_type: Option<PackageType>,
63
64    /// Filter packages by a fuzzy search on the name.
65    #[builder(setter(into), default)]
66    package_name: Option<Cow<'a, str>>,
67    /// Filter packages by the version.
68    #[builder(setter(into), default)]
69    package_version: Option<Cow<'a, str>>,
70
71    /// Include versionless packages.
72    #[builder(default)]
73    include_versionless: Option<bool>,
74
75    /// Filter based on the status of the package.
76    #[builder(default)]
77    status: Option<PackageStatus>,
78}
79
80impl<'a> Packages<'a> {
81    /// Create a builder for the endpoint.
82    pub fn builder() -> PackagesBuilder<'a> {
83        PackagesBuilder::default()
84    }
85}
86
87impl Endpoint for Packages<'_> {
88    fn method(&self) -> Method {
89        Method::GET
90    }
91
92    fn endpoint(&self) -> Cow<'static, str> {
93        format!("projects/{}/packages", self.project).into()
94    }
95
96    fn parameters(&self) -> QueryParams {
97        let mut params = QueryParams::default();
98
99        params
100            .push_opt("order_by", self.order_by)
101            .push_opt("sort", self.sort)
102            .push_opt("package_type", self.package_type)
103            .push_opt("package_name", self.package_name.as_ref())
104            .push_opt("package_version", self.package_version.as_ref())
105            .push_opt("include_versionless", self.include_versionless)
106            .push_opt("status", self.status);
107
108        params
109    }
110}
111
112impl Pageable for Packages<'_> {}
113
114#[cfg(test)]
115mod tests {
116    use super::{PackageOrderBy, PackageStatus, PackageType};
117    use crate::{
118        api::{
119            self,
120            common::SortOrder,
121            projects::packages::packages::{Packages, PackagesBuilderError},
122            Query,
123        },
124        test::client::{ExpectedUrl, SingleTestClient},
125    };
126
127    #[test]
128    fn order_by_as_str() {
129        let items = &[
130            (PackageOrderBy::CreatedAt, "created_at"),
131            (PackageOrderBy::Name, "name"),
132            (PackageOrderBy::Type, "type"),
133            (PackageOrderBy::Version, "version"),
134        ];
135
136        for (i, s) in items {
137            assert_eq!(i.as_str(), *s);
138        }
139    }
140
141    #[test]
142    fn project_is_needed() {
143        let err = Packages::builder().build().unwrap_err();
144        crate::test::assert_missing_field!(err, PackagesBuilderError, "project");
145    }
146
147    #[test]
148    fn project_is_sufficient() {
149        Packages::builder().project(1).build().unwrap();
150    }
151
152    #[test]
153    fn endpoint() {
154        let endpoint = ExpectedUrl::builder()
155            .endpoint("projects/1337/packages")
156            .build()
157            .unwrap();
158        let client = SingleTestClient::new_raw(endpoint, "");
159
160        let endpoint = Packages::builder().project(1337).build().unwrap();
161        api::ignore(endpoint).query(&client).unwrap();
162    }
163
164    #[test]
165    fn endpoint_order_by() {
166        let endpoint = ExpectedUrl::builder()
167            .endpoint("projects/1337/packages")
168            .add_query_params(&[("order_by", "name")])
169            .build()
170            .unwrap();
171        let client = SingleTestClient::new_raw(endpoint, "");
172
173        let endpoint = Packages::builder()
174            .project(1337)
175            .order_by(PackageOrderBy::Name)
176            .build()
177            .unwrap();
178        api::ignore(endpoint).query(&client).unwrap();
179    }
180
181    #[test]
182    fn endpoint_sort() {
183        let endpoint = ExpectedUrl::builder()
184            .endpoint("projects/1337/packages")
185            .add_query_params(&[("sort", "desc")])
186            .build()
187            .unwrap();
188        let client = SingleTestClient::new_raw(endpoint, "");
189
190        let endpoint = Packages::builder()
191            .project(1337)
192            .sort(SortOrder::Descending)
193            .build()
194            .unwrap();
195        api::ignore(endpoint).query(&client).unwrap();
196    }
197
198    #[test]
199    fn endpoint_package_type() {
200        let endpoint = ExpectedUrl::builder()
201            .endpoint("projects/1337/packages")
202            .add_query_params(&[("package_type", "conan")])
203            .build()
204            .unwrap();
205        let client = SingleTestClient::new_raw(endpoint, "");
206
207        let endpoint = Packages::builder()
208            .project(1337)
209            .package_type(PackageType::Conan)
210            .build()
211            .unwrap();
212        api::ignore(endpoint).query(&client).unwrap();
213    }
214
215    #[test]
216    fn endpoint_package_name() {
217        let endpoint = ExpectedUrl::builder()
218            .endpoint("projects/1337/packages")
219            .add_query_params(&[("package_name", "test")])
220            .build()
221            .unwrap();
222        let client = SingleTestClient::new_raw(endpoint, "");
223
224        let endpoint = Packages::builder()
225            .project(1337)
226            .package_name("test")
227            .build()
228            .unwrap();
229        api::ignore(endpoint).query(&client).unwrap();
230    }
231
232    #[test]
233    fn endpoint_package_version() {
234        let endpoint = ExpectedUrl::builder()
235            .endpoint("projects/1337/packages")
236            .add_query_params(&[("package_version", "1.2.3")])
237            .build()
238            .unwrap();
239        let client = SingleTestClient::new_raw(endpoint, "");
240
241        let endpoint = Packages::builder()
242            .project(1337)
243            .package_version("1.2.3")
244            .build()
245            .unwrap();
246        api::ignore(endpoint).query(&client).unwrap();
247    }
248
249    #[test]
250    fn endpoint_include_versionless() {
251        let endpoint = ExpectedUrl::builder()
252            .endpoint("projects/1337/packages")
253            .add_query_params(&[("include_versionless", "true")])
254            .build()
255            .unwrap();
256        let client = SingleTestClient::new_raw(endpoint, "");
257
258        let endpoint = Packages::builder()
259            .project(1337)
260            .include_versionless(true)
261            .build()
262            .unwrap();
263        api::ignore(endpoint).query(&client).unwrap();
264    }
265    #[test]
266    fn endpoint_status() {
267        let endpoint = ExpectedUrl::builder()
268            .endpoint("projects/1337/packages")
269            .add_query_params(&[("status", "processing")])
270            .build()
271            .unwrap();
272        let client = SingleTestClient::new_raw(endpoint, "");
273
274        let endpoint = Packages::builder()
275            .project(1337)
276            .status(PackageStatus::Processing)
277            .build()
278            .unwrap();
279        api::ignore(endpoint).query(&client).unwrap();
280    }
281}