1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct PullRequest {
8 pub number: u64,
10
11 pub title: String,
13
14 pub body: Option<String>,
16
17 pub state: PullRequestState,
19
20 pub draft: bool,
22
23 pub head_branch: String,
25
26 pub base_branch: String,
28
29 pub html_url: String,
31
32 pub mergeable: Option<bool>,
34
35 pub mergeable_state: Option<String>,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(rename_all = "lowercase")]
42pub enum PullRequestState {
43 Open,
45 Closed,
47 Merged,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct CheckRun {
54 pub name: String,
56
57 pub status: CheckStatus,
59
60 pub details_url: Option<String>,
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
66#[serde(rename_all = "lowercase")]
67pub enum CheckStatus {
68 Queued,
70 InProgress,
72 Success,
74 Failure,
76 Skipped,
78 Cancelled,
80}
81
82impl CheckStatus {
83 #[must_use]
85 pub const fn is_success(&self) -> bool {
86 matches!(self, Self::Success | Self::Skipped)
87 }
88
89 #[must_use]
91 pub const fn is_failure(&self) -> bool {
92 matches!(self, Self::Failure)
93 }
94
95 #[must_use]
97 pub const fn is_pending(&self) -> bool {
98 matches!(self, Self::Queued | Self::InProgress)
99 }
100}
101
102#[derive(Debug, Serialize)]
104pub struct CreatePullRequest {
105 pub title: String,
107
108 pub body: String,
110
111 pub head: String,
113
114 pub base: String,
116
117 pub draft: bool,
119}
120
121#[derive(Debug, Serialize)]
123pub struct UpdatePullRequest {
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub title: Option<String>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub body: Option<String>,
131
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub base: Option<String>,
135}
136
137#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
139#[serde(rename_all = "lowercase")]
140pub enum MergeMethod {
141 Merge,
143 #[default]
145 Squash,
146 Rebase,
148}
149
150#[derive(Debug, Serialize)]
152pub struct MergePullRequest {
153 #[serde(skip_serializing_if = "Option::is_none")]
155 pub commit_title: Option<String>,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
159 pub commit_message: Option<String>,
160
161 pub merge_method: MergeMethod,
163}
164
165#[derive(Debug, Clone, Deserialize)]
167pub struct MergeResult {
168 pub sha: String,
170
171 pub merged: bool,
173
174 pub message: String,
176}
177
178#[derive(Debug, Clone, Deserialize)]
180pub struct IssueComment {
181 pub id: u64,
183
184 pub body: Option<String>,
186}
187
188#[derive(Debug, Serialize)]
190pub struct CreateComment {
191 pub body: String,
193}
194
195#[derive(Debug, Serialize)]
197pub struct UpdateComment {
198 pub body: String,
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205
206 #[test]
207 fn test_check_status_is_success() {
208 assert!(CheckStatus::Success.is_success());
209 assert!(CheckStatus::Skipped.is_success());
210 assert!(!CheckStatus::Failure.is_success());
211 assert!(!CheckStatus::Queued.is_success());
212 assert!(!CheckStatus::InProgress.is_success());
213 assert!(!CheckStatus::Cancelled.is_success());
214 }
215
216 #[test]
217 fn test_check_status_is_failure() {
218 assert!(CheckStatus::Failure.is_failure());
219 assert!(!CheckStatus::Success.is_failure());
220 assert!(!CheckStatus::Skipped.is_failure());
221 assert!(!CheckStatus::Queued.is_failure());
222 assert!(!CheckStatus::InProgress.is_failure());
223 assert!(!CheckStatus::Cancelled.is_failure());
224 }
225
226 #[test]
227 fn test_check_status_is_pending() {
228 assert!(CheckStatus::Queued.is_pending());
229 assert!(CheckStatus::InProgress.is_pending());
230 assert!(!CheckStatus::Success.is_pending());
231 assert!(!CheckStatus::Failure.is_pending());
232 assert!(!CheckStatus::Skipped.is_pending());
233 assert!(!CheckStatus::Cancelled.is_pending());
234 }
235
236 #[test]
237 fn test_pull_request_state_equality() {
238 assert_eq!(PullRequestState::Open, PullRequestState::Open);
239 assert_eq!(PullRequestState::Closed, PullRequestState::Closed);
240 assert_eq!(PullRequestState::Merged, PullRequestState::Merged);
241 assert_ne!(PullRequestState::Open, PullRequestState::Closed);
242 }
243
244 #[test]
245 fn test_merge_method_default() {
246 assert_eq!(MergeMethod::default(), MergeMethod::Squash);
247 }
248
249 #[test]
250 #[allow(clippy::unwrap_used)]
251 fn test_pull_request_state_serialization() {
252 assert_eq!(
253 serde_json::to_string(&PullRequestState::Open).unwrap(),
254 "\"open\""
255 );
256 assert_eq!(
257 serde_json::to_string(&PullRequestState::Closed).unwrap(),
258 "\"closed\""
259 );
260 assert_eq!(
261 serde_json::to_string(&PullRequestState::Merged).unwrap(),
262 "\"merged\""
263 );
264 }
265
266 #[test]
267 #[allow(clippy::unwrap_used)]
268 fn test_check_status_serialization() {
269 assert_eq!(
270 serde_json::to_string(&CheckStatus::Queued).unwrap(),
271 "\"queued\""
272 );
273 assert_eq!(
274 serde_json::to_string(&CheckStatus::InProgress).unwrap(),
275 "\"inprogress\""
276 );
277 assert_eq!(
278 serde_json::to_string(&CheckStatus::Success).unwrap(),
279 "\"success\""
280 );
281 }
282
283 #[test]
284 #[allow(clippy::unwrap_used)]
285 fn test_merge_method_serialization() {
286 assert_eq!(
287 serde_json::to_string(&MergeMethod::Merge).unwrap(),
288 "\"merge\""
289 );
290 assert_eq!(
291 serde_json::to_string(&MergeMethod::Squash).unwrap(),
292 "\"squash\""
293 );
294 assert_eq!(
295 serde_json::to_string(&MergeMethod::Rebase).unwrap(),
296 "\"rebase\""
297 );
298 }
299}