1use serde::Deserialize;
2
3use crate::{
4 error::PlatformError,
5 platform::{Release, ReleaseAsset, ReleasePlatform},
6};
7
8pub struct Gitlab;
9impl ReleasePlatform for Gitlab {
10 const API_BASE_PRIMARY: &'static str = "https://gitlab.com";
11
12 const API_BASE_PKGFORGE: &'static str = "https://api.gl.pkgforge.dev";
13
14 const TOKEN_ENV_VAR: &'static str = "GITLAB_TOKEN";
15
16 fn format_project_path(project: &str) -> Result<(String, String), PlatformError> {
17 if project.chars().all(|c| c.is_numeric()) {
18 Ok((project.to_string(), String::new()))
19 } else {
20 match project.split_once('/') {
21 Some((owner, repo)) => Ok((owner.to_string(), repo.to_string())),
22 None => Ok((project.to_string(), String::new())),
23 }
24 }
25 }
26
27 fn format_api_path(project: &str, tag: Option<&str>) -> Result<String, PlatformError> {
28 let encoded_path = project.replace('/', "%2F");
29
30 let base_path = format!("/api/v4/projects/{}/releases", encoded_path);
31
32 if let Some(tag) = tag {
33 if project.chars().all(char::is_numeric) {
34 return Ok(format!("{}/{}", base_path, tag));
35 }
36 }
37 Ok(base_path)
38 }
39}
40
41#[derive(Debug, Deserialize)]
42pub struct GitlabAssets {
43 pub links: Vec<GitlabAsset>,
44}
45
46#[derive(Debug, Deserialize)]
47pub struct GitlabRelease {
48 name: String,
49 tag_name: String,
50 upcoming_release: bool,
51 released_at: String,
52 assets: GitlabAssets,
53}
54
55impl Release<GitlabAsset> for GitlabRelease {
56 fn name(&self) -> &str {
57 &self.name
58 }
59
60 fn tag_name(&self) -> &str {
61 &self.tag_name
62 }
63
64 fn is_prerelease(&self) -> bool {
65 self.upcoming_release
66 }
67
68 fn published_at(&self) -> &str {
69 &self.released_at
70 }
71
72 fn assets(&self) -> Vec<GitlabAsset> {
73 self.assets.links.clone()
74 }
75}
76
77#[derive(Clone, Debug, Deserialize)]
78pub struct GitlabAsset {
79 pub name: String,
80 pub direct_asset_url: String,
81}
82
83impl ReleaseAsset for GitlabAsset {
84 fn name(&self) -> &str {
85 &self.name
86 }
87
88 fn size(&self) -> Option<u64> {
89 None
90 }
91
92 fn download_url(&self) -> &str {
93 &self.direct_asset_url
94 }
95}