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