use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Role {
Author,
Reviewer,
Assignee,
}
#[allow(clippy::enum_variant_names)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum Mergeable {
Mergeable,
Conflicting,
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum MergeStateStatus {
Clean,
Dirty,
Blocked,
Behind,
Unstable,
HasHooks,
Draft,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ReviewDecision {
Approved,
ChangesRequested,
ReviewRequired,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum CheckState {
Success,
Failure,
Error,
Pending,
Expected,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ReviewState {
Approved,
ChangesRequested,
Commented,
Dismissed,
Pending,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Review {
pub author: String,
pub state: ReviewState,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CheckRun {
pub name: String,
pub workflow_name: Option<String>,
pub conclusion: Option<String>,
pub status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PullRequest {
pub number: u32,
pub title: String,
pub url: String,
pub repo: String,
pub author: String,
pub is_draft: bool,
pub mergeable: Mergeable,
pub merge_state: MergeStateStatus,
pub review_decision: Option<ReviewDecision>,
pub commits_count: u32,
pub comments_count: u32,
pub check_state: Option<CheckState>,
pub failing_checks: Vec<CheckRun>,
pub unresolved_threads: u32,
pub requested_reviewers: Vec<String>,
pub reviews: Vec<Review>,
pub updated_at: DateTime<Utc>,
pub roles: Vec<Role>,
pub base_ref: Option<String>,
pub head_ref: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Label {
pub name: String,
pub color: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Issue {
pub number: u32,
pub title: String,
pub url: String,
pub repo: String,
pub author: String,
pub comments_count: u32,
pub updated_at: DateTime<Utc>,
pub labels: Vec<Label>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Inbox {
pub viewer_login: String,
pub prs: Vec<PullRequest>,
pub issues: Vec<Issue>,
}
#[must_use]
pub(crate) fn sorted_prs_for_repo<'a>(inbox: &'a Inbox, repo: &str) -> Vec<&'a PullRequest> {
let mut prs: Vec<&PullRequest> = inbox.prs.iter().filter(|pr| pr.repo == repo).collect();
prs.sort_by(|a, b| b.updated_at.cmp(&a.updated_at).then_with(|| a.number.cmp(&b.number)));
prs
}
#[must_use]
pub(crate) fn sorted_issues_for_repo<'a>(inbox: &'a Inbox, repo: &str) -> Vec<&'a Issue> {
let mut issues: Vec<&Issue> = inbox.issues.iter().filter(|i| i.repo == repo).collect();
issues.sort_by(|a, b| b.updated_at.cmp(&a.updated_at).then_with(|| a.number.cmp(&b.number)));
issues
}