1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Deserialize, Debug)]
5pub struct User {
6 pub id: usize,
7 pub username: String,
8}
9
10#[derive(Deserialize, Debug)]
11pub struct Pipeline {
12 pub id: usize,
13 pub sha: String,
14 #[serde(rename = "ref")]
15 pub branch: String,
16 pub status: String,
17 pub updated_at: DateTime<Utc>,
18}
19
20#[derive(Deserialize, Debug)]
21pub struct Emoji {
22 pub id: usize,
23 pub name: String,
24 pub user: User,
25 pub awardable_id: usize,
26 pub awardable_type: String,
27}
28
29#[derive(Deserialize, Debug)]
33pub struct MergeRequest {
34 pub title: String,
35 pub description: Option<String>,
36 pub project_id: usize,
37 pub iid: usize, pub work_in_progress: bool,
39 pub author: User,
40 pub merge_status: String,
41 pub source_branch: String,
42 pub target_branch: String,
43 pub sha: String,
44 pub references: Reference,
45 pub web_url: String,
46 pub main_issue: Option<Issue>,
47}
48
49#[derive(Serialize, Debug, Default)]
50pub struct CreateMergeRequest {
51 #[serde(rename = "id")]
52 pub project_id: String,
53 pub source_branch: String,
54 pub target_branch: String,
55 pub title: String,
56 pub milestone_id: Option<usize>,
57 pub description: Option<String>,
58 pub assignee_ids: Vec<usize>,
59 pub labels: Option<String>,
61}
62
63#[derive(Deserialize, Debug)]
64pub struct MergeRequestDetails {
65 pub title: String,
66 pub project_id: usize,
67 pub iid: usize, pub work_in_progress: bool,
69 pub author: User,
70 pub merge_status: String,
71 pub source_branch: String,
72 pub target_branch: String,
73 pub sha: Option<String>,
74 pub rebase_in_progress: Option<bool>,
76 pub merge_error: Option<String>,
77 pub pipeline: Option<Pipeline>,
78 pub diverged_commits_count: Option<i32>,
80}
81
82#[derive(Deserialize, Debug)]
83#[serde(rename_all = "lowercase")]
84pub enum MergeRequestState {
85 Opened,
86 Closed,
87 Merged,
88}
89
90impl MergeRequestState {
91 pub fn name(&self) -> &str {
92 match self {
93 MergeRequestState::Opened => "opened",
94 MergeRequestState::Closed => "closed",
95 MergeRequestState::Merged => "merged",
96 }
97 }
98}
99
100impl std::str::FromStr for MergeRequestState {
101 type Err = String;
102 fn from_str(state: &str) -> Result<Self, Self::Err> {
103 match state {
104 "opened" => Ok(MergeRequestState::Opened),
105 "closed" => Ok(MergeRequestState::Closed),
106 "merged" => Ok(MergeRequestState::Merged),
107 other_state => Err(format!(
108 "Invalid state, {} not in [opened, closed, merged]",
109 other_state
110 )
111 .to_string()),
112 }
113 }
114}
115
116#[derive(Deserialize, Debug)]
117pub struct ProjectMilestone {
118 pub title: String,
119 pub id: usize,
120 pub iid: usize,
121 pub project_id: Option<usize>,
122 pub group_id: Option<usize>,
123 pub description: String,
124 pub due_date: Option<String>,
125 pub start_date: Option<String>,
126 pub state: String,
127}
128
129#[derive(Serialize, Debug)]
130pub struct CreateProjectMilestone {
131 #[serde(rename = "id")]
132 pub project_id: usize,
133 pub title: String,
134 pub description: Option<String>,
135}
136
137#[derive(Deserialize, Debug)]
138pub struct Issue {
139 pub title: String,
140 pub iid: usize, pub state: IssueState,
142 pub description: Option<String>,
143 pub author: User,
144 pub milestone: Option<ProjectMilestone>,
145 pub project_id: usize,
146 pub assignees: Vec<User>,
147 pub web_url: String,
148 pub weight: Option<usize>,
149 pub labels: Vec<String>,
150 pub references: Reference,
151}
152
153#[derive(Deserialize, Debug)]
154pub struct Reference {
155 pub short: String,
156 pub relative: String,
157 pub full: String,
158}
159
160#[derive(Serialize, Debug, Default)]
161pub struct CreateIssue {
162 #[serde(rename = "id")]
163 pub project_id: String,
164 pub title: String,
165 pub description: Option<String>,
166 pub milestone_id: Option<usize>,
167 pub assignee_ids: Vec<usize>,
168 pub weight: Option<usize>,
169 pub labels: Option<String>,
171}
172
173#[derive(Deserialize, Debug)]
174#[serde(rename_all = "lowercase")]
175pub enum IssueState {
176 All,
177 Opened,
178 Closed,
179}
180
181impl IssueState {
182 pub fn name(&self) -> &str {
183 match self {
184 IssueState::All => "all",
185 IssueState::Closed => "closed",
186 IssueState::Opened => "opened",
187 }
188 }
189}
190
191impl std::str::FromStr for IssueState {
192 type Err = String;
193 fn from_str(state: &str) -> Result<Self, Self::Err> {
194 match state {
195 "all" => Ok(IssueState::All),
196 "closed" => Ok(IssueState::Closed),
197 "opened" => Ok(IssueState::Opened),
198 other_state => Err(format!(
199 "Invalid state, {} not in [all, opened, closed]",
200 other_state
201 )
202 .to_string()),
203 }
204 }
205}
206
207#[derive(Serialize, Debug)]
208pub struct RebaseBranch {
209 pub id: usize,
210 pub merge_request_iid: usize,
211}
212
213impl<'a> From<&'a MergeRequest> for RebaseBranch {
214 fn from(mr: &'a MergeRequest) -> RebaseBranch {
215 RebaseBranch {
216 id: mr.project_id,
217 merge_request_iid: mr.iid,
218 }
219 }
220}
221
222#[derive(Serialize, Debug)]
223pub struct RemoveSourceBranch {
224 pub id: usize,
225 pub merge_request_iid: usize,
226 pub remove_source_branch: bool,
227}
228
229impl<'a> From<&'a MergeRequest> for RemoveSourceBranch {
230 fn from(mr: &'a MergeRequest) -> RemoveSourceBranch {
231 RemoveSourceBranch {
232 id: mr.project_id,
233 merge_request_iid: mr.iid,
234 remove_source_branch: true,
235 }
236 }
237}
238
239#[derive(Serialize, Debug)]
240pub struct ListPipelines {
241 pub id: usize,
242 pub merge_request_iid: usize,
243}
244
245impl<'a> From<&'a MergeRequest> for ListPipelines {
246 fn from(mr: &'a MergeRequest) -> ListPipelines {
247 ListPipelines {
248 id: mr.project_id,
249 merge_request_iid: mr.iid,
250 }
251 }
252}
253
254#[derive(Serialize, Debug)]
255pub struct AcceptMergeRequest {
256 pub id: usize,
257 pub merge_request_iid: usize,
258 pub merge_when_pipeline_succeeds: bool,
259 pub should_remove_source_branch: bool,
260 pub sha: String,
261}
262
263impl<'a> From<&'a MergeRequest> for AcceptMergeRequest {
264 fn from(mr: &'a MergeRequest) -> AcceptMergeRequest {
265 AcceptMergeRequest {
266 id: mr.project_id,
267 merge_request_iid: mr.iid,
268 merge_when_pipeline_succeeds: true,
269 should_remove_source_branch: true,
270 sha: mr.sha.clone(),
271 }
272 }
273}
274
275#[derive(Serialize, Debug)]
276pub struct GetMergeRequestDetails {
277 pub id: usize,
278 pub merge_request_iid: usize,
279 pub include_diverged_commits_count: bool,
280 pub include_rebase_in_progress: bool,
281}
282
283impl GetMergeRequestDetails {
284 pub fn new(project_id: usize, merge_request_iid: usize) -> Self {
285 GetMergeRequestDetails {
286 id: project_id,
287 merge_request_iid,
288 include_diverged_commits_count: true,
289 include_rebase_in_progress: true,
290 }
291 }
292}
293
294impl<'a> From<&'a MergeRequest> for GetMergeRequestDetails {
295 fn from(mr: &'a MergeRequest) -> GetMergeRequestDetails {
296 GetMergeRequestDetails::new(mr.project_id, mr.iid)
297 }
298}
299
300#[derive(Serialize, Debug)]
301pub struct AwardEmoji {
302 pub id: usize,
303 pub awardable_id: usize,
304}
305
306impl<'a> From<&'a MergeRequest> for AwardEmoji {
307 fn from(mr: &'a MergeRequest) -> AwardEmoji {
308 AwardEmoji {
309 id: mr.project_id,
310 awardable_id: mr.iid,
311 }
312 }
313}
314
315#[derive(Deserialize, Debug)]
316pub struct Project {
317 pub id: usize,
318 pub description: Option<String>,
319 pub ssh_url_to_repo: String,
320 pub http_url_to_repo: String,
321 pub web_url: String,
322 pub name: String,
323 pub name_with_namespace: String,
324 pub path: String,
325 pub path_with_namespace: String,
326 pub avatar_url: Option<String>,
327}