git_cliff_core/remote/
gitea.rs1use crate::config::Remote;
2use crate::error::*;
3use reqwest_middleware::ClientWithMiddleware;
4use serde::{
5 Deserialize,
6 Serialize,
7};
8
9use super::*;
10
11pub const START_FETCHING_MSG: &str = "Retrieving data from Gitea...";
13
14pub const FINISHED_FETCHING_MSG: &str = "Done fetching Gitea data.";
16
17pub(crate) const TEMPLATE_VARIABLES: &[&str] =
19 &["gitea", "commit.gitea", "commit.remote"];
20
21#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct GiteaCommit {
24 pub sha: String,
26 pub author: Option<GiteaCommitAuthor>,
28 pub created: String,
30}
31
32impl RemoteCommit for GiteaCommit {
33 fn id(&self) -> String {
34 self.sha.clone()
35 }
36
37 fn username(&self) -> Option<String> {
38 self.author.clone().and_then(|v| v.login)
39 }
40
41 fn timestamp(&self) -> Option<i64> {
42 Some(self.convert_to_unix_timestamp(self.created.clone().as_str()))
43 }
44}
45
46impl RemoteEntry for GiteaCommit {
47 fn url(
48 _id: i64,
49 api_url: &str,
50 remote: &Remote,
51 ref_name: Option<&str>,
52 page: i32,
53 ) -> String {
54 let mut url = format!(
55 "{}/api/v1/repos/{}/{}/commits?limit={MAX_PAGE_SIZE}&page={page}",
56 api_url, remote.owner, remote.repo
57 );
58
59 if let Some(ref_name) = ref_name {
60 url.push_str(&format!("&sha={}", ref_name));
61 }
62
63 url
64 }
65
66 fn buffer_size() -> usize {
67 10
68 }
69
70 fn early_exit(&self) -> bool {
71 false
72 }
73}
74
75#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
77pub struct GiteaCommitAuthor {
78 pub login: Option<String>,
80}
81
82#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct PullRequestLabel {
86 pub name: String,
88}
89
90#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
92pub struct GiteaPullRequest {
93 pub number: i64,
95 pub title: Option<String>,
97 pub merge_commit_sha: Option<String>,
99 pub labels: Vec<PullRequestLabel>,
101}
102
103impl RemotePullRequest for GiteaPullRequest {
104 fn number(&self) -> i64 {
105 self.number
106 }
107
108 fn title(&self) -> Option<String> {
109 self.title.clone()
110 }
111
112 fn labels(&self) -> Vec<String> {
113 self.labels.iter().map(|v| v.name.clone()).collect()
114 }
115
116 fn merge_commit(&self) -> Option<String> {
117 self.merge_commit_sha.clone()
118 }
119}
120
121impl RemoteEntry for GiteaPullRequest {
122 fn url(
123 _id: i64,
124 api_url: &str,
125 remote: &Remote,
126 _ref_name: Option<&str>,
127 page: i32,
128 ) -> String {
129 format!(
130 "{}/api/v1/repos/{}/{}/pulls?limit={MAX_PAGE_SIZE}&page={page}&\
131 state=closed",
132 api_url, remote.owner, remote.repo
133 )
134 }
135
136 fn buffer_size() -> usize {
137 5
138 }
139
140 fn early_exit(&self) -> bool {
141 false
142 }
143}
144
145#[derive(Debug, Clone)]
147pub struct GiteaClient {
148 remote: Remote,
150 client: ClientWithMiddleware,
152}
153
154impl TryFrom<Remote> for GiteaClient {
156 type Error = Error;
157 fn try_from(remote: Remote) -> Result<Self> {
158 Ok(Self {
159 client: remote.create_client("application/json")?,
160 remote,
161 })
162 }
163}
164
165impl RemoteClient for GiteaClient {
166 const API_URL: &'static str = "https://codeberg.org";
167 const API_URL_ENV: &'static str = "GITEA_API_URL";
168
169 fn remote(&self) -> Remote {
170 self.remote.clone()
171 }
172
173 fn client(&self) -> ClientWithMiddleware {
174 self.client.clone()
175 }
176}
177
178impl GiteaClient {
179 pub async fn get_commits(
181 &self,
182 ref_name: Option<&str>,
183 ) -> Result<Vec<Box<dyn RemoteCommit>>> {
184 Ok(self
185 .fetch::<GiteaCommit>(0, ref_name)
186 .await?
187 .into_iter()
188 .map(|v| Box::new(v) as Box<dyn RemoteCommit>)
189 .collect())
190 }
191
192 pub async fn get_pull_requests(
194 &self,
195 ref_name: Option<&str>,
196 ) -> Result<Vec<Box<dyn RemotePullRequest>>> {
197 Ok(self
198 .fetch::<GiteaPullRequest>(0, ref_name)
199 .await?
200 .into_iter()
201 .map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
202 .collect())
203 }
204}
205
206#[cfg(test)]
207mod test {
208 use super::*;
209 use crate::remote::RemoteCommit;
210 use pretty_assertions::assert_eq;
211
212 #[test]
213 fn timestamp() {
214 let remote_commit = GiteaCommit {
215 sha: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
216 author: Some(GiteaCommitAuthor {
217 login: Some(String::from("orhun")),
218 }),
219 created: String::from("2021-07-18T15:14:39+03:00"),
220 };
221
222 assert_eq!(Some(1626610479), remote_commit.timestamp());
223 }
224}