use crate::schema::schema;
use crate::api::model::{MergeState, Mergeable, ReviewDecision, ReviewState, Side, ViewedState};
#[derive(cynic::Scalar, Debug, Clone)]
pub struct DateTime(pub String);
#[derive(cynic::Scalar, Debug, Clone)]
#[cynic(graphql_type = "URI")]
pub struct Uri(pub String);
#[derive(cynic::Scalar, Debug, Clone)]
#[cynic(graphql_type = "GitObjectID")]
pub struct GitObjectId(pub String);
#[derive(cynic::Scalar, Debug, Clone)]
pub struct BigInt(pub String);
pub(crate) fn nodes<T>(list: Option<Vec<Option<T>>>) -> impl Iterator<Item = T> {
list.into_iter().flatten().flatten()
}
macro_rules! fragments {
($field:ident: Option<$ty:ident>; $($name:ident = $graphql:literal),* $(,)?) => {$(
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = $graphql)]
pub struct $name {
pub $field: Option<$ty>,
}
)*};
(total_count: i32; $($name:ident = $graphql:literal),* $(,)?) => {$(
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = $graphql)]
pub struct $name {
pub total_count: i32,
}
)*};
(id: cynic::Id; $($name:ident = $graphql:literal),* $(,)?) => {$(
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = $graphql)]
pub struct $name {
pub id: cynic::Id,
}
)*};
(counted: $($name:ident = $graphql:literal => $ty:ident),* $(,)?) => {$(
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = $graphql)]
pub struct $name {
pub total_count: i32,
pub nodes: Option<Vec<Option<$ty>>>,
}
)*};
(nodes: $($name:ident = $graphql:literal => $ty:ident),* $(,)?) => {$(
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = $graphql)]
pub struct $name {
pub nodes: Option<Vec<Option<$ty>>>,
}
)*};
}
pub(crate) use fragments;
fragments! {
total_count: i32;
CommentCount = "IssueCommentConnection",
UserCount = "UserConnection",
IssueCount = "IssueConnection",
PrCount = "PullRequestConnection",
CommitCount = "CommitHistoryConnection",
ReviewCommentCount = "PullRequestReviewCommentConnection",
FollowCount = "FollowerConnection",
FollowingCount = "FollowingConnection",
RefCount = "RefConnection",
}
fragments! {
client_mutation_id: Option<String>;
MarkFileAsViewedPayload = "MarkFileAsViewedPayload",
UnmarkFileAsViewedPayload = "UnmarkFileAsViewedPayload",
AddCommentPayload = "AddCommentPayload",
StarPayload = "AddStarPayload",
UnstarPayload = "RemoveStarPayload",
MergePayload = "MergePullRequestPayload",
ClosePrPayload = "ClosePullRequestPayload",
ReopenPrPayload = "ReopenPullRequestPayload",
CloseIssuePayload = "CloseIssuePayload",
ReopenIssuePayload = "ReopenIssuePayload",
ReadyPayload = "MarkPullRequestReadyForReviewPayload",
UpdateBranchPayload = "UpdatePullRequestBranchPayload",
AutoMergePayload = "EnablePullRequestAutoMergePayload",
NoAutoMergePayload = "DisablePullRequestAutoMergePayload",
EnqueuePayload = "EnqueuePullRequestPayload",
DequeuePayload = "DequeuePullRequestPayload",
}
fragments! {
id: cynic::Id;
ReviewId = "PullRequestReview",
ThreadId = "PullRequestReviewThread",
CommentId = "PullRequestReviewComment",
}
fragments! {
pull_request_review: Option<ReviewId>;
StartReviewPayload = "AddPullRequestReviewPayload",
SubmitReviewPayload = "SubmitPullRequestReviewPayload",
}
fragments! {
thread: Option<ThreadId>;
ThreadPayload = "AddPullRequestReviewThreadPayload",
ResolvePayload = "ResolveReviewThreadPayload",
UnresolvePayload = "UnresolveReviewThreadPayload",
}
fragments! {
counted:
LabelConnection = "LabelConnection" => Label,
ReviewCommentConnection = "PullRequestReviewCommentConnection" => ReviewComment,
FirstCommentConnection = "PullRequestReviewCommentConnection" => FirstComment,
}
fragments! {
nodes:
CommitRollupConnection = "PullRequestCommitConnection" => CommitRollupNode,
PendingReviewConnection = "PullRequestReviewConnection" => PendingReview,
ReviewCommitConnection = "PullRequestReviewConnection" => ReviewCommit,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct NumberVariables {
pub owner: String,
pub name: String,
pub number: i32,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct PageVariables {
pub owner: String,
pub name: String,
pub number: i32,
pub after: Option<String>,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct NodesVariables {
pub ids: Vec<cynic::Id>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "NodesVariables")]
pub struct RollupsQuery {
#[arguments(ids: $ids)]
pub nodes: Vec<Option<RollupNode>>,
}
#[derive(cynic::InlineFragments, Debug)]
#[cynic(graphql_type = "Node")]
pub enum RollupNode {
PullRequest(PrRollup),
#[cynic(fallback)]
Other,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest")]
pub struct PrRollup {
pub id: cynic::Id,
#[arguments(last: 1)]
pub commits: CommitRollupConnection,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest")]
pub struct PrSummary {
pub title: String,
#[cynic(spread)]
pub status: crate::api::model::PrStatus,
pub updated_at: DateTime,
pub author: Option<Actor>,
pub additions: i32,
pub deletions: i32,
pub review_decision: Option<ReviewDecision>,
#[arguments(last: 1)]
pub commits: CommitRollupConnection,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct Actor {
pub login: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository")]
pub struct RepositoryName {
pub name_with_owner: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Milestone")]
pub struct MilestoneName {
pub number: i32,
pub title: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestCommit")]
pub struct CommitRollupNode {
pub commit: CommitRollup,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Commit")]
pub struct CommitRollup {
pub status_check_rollup: Option<StatusCheckRollup>,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct StatusCheckRollup {
pub state: StatusState,
}
#[derive(cynic::Enum, Debug, Clone, Copy)]
pub enum PullRequestState {
Open,
Closed,
Merged,
}
#[derive(cynic::Enum, Debug, Clone, Copy)]
pub enum StatusState {
Error,
Expected,
Failure,
Pending,
Success,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "NumberVariables")]
pub struct PullRequestQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryWithPr>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "NumberVariables")]
pub struct RepositoryWithPr {
#[arguments(number: $number)]
pub pull_request: Option<PrDetail>,
pub merge_commit_allowed: bool,
pub squash_merge_allowed: bool,
pub rebase_merge_allowed: bool,
pub viewer_default_merge_method: crate::api::change::MergeMethod,
pub viewer_permission: Option<RepositoryPermission>,
pub auto_merge_allowed: bool,
}
#[derive(cynic::Enum, Debug, Clone, Copy, PartialEq, Eq)]
pub enum RepositoryPermission {
Admin,
Maintain,
Write,
TriagePlus,
Triage,
Read,
}
impl RepositoryPermission {
pub fn writes(permission: Option<Self>) -> bool {
matches!(permission, Some(Self::Admin | Self::Maintain | Self::Write))
}
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest")]
pub struct PrDetail {
pub id: cynic::Id,
#[cynic(spread)]
pub summary: PrSummary,
pub body: String,
pub created_at: DateTime,
pub base_ref_name: String,
pub head_ref_name: String,
pub base_ref_oid: GitObjectId,
pub head_ref_oid: GitObjectId,
pub head_repository: Option<RepositoryName>,
pub changed_files: i32,
pub mergeable: Mergeable,
pub merge_state_status: MergeState,
pub viewer_can_close: bool,
pub viewer_can_reopen: bool,
pub viewer_can_update: bool,
pub viewer_can_merge_as_admin: bool,
pub viewer_did_author: bool,
pub maintainer_can_modify: bool,
pub is_cross_repository: bool,
pub viewer_can_enable_auto_merge: bool,
pub viewer_can_disable_auto_merge: bool,
pub auto_merge_request: Option<AutoMergeRequest>,
pub is_merge_queue_enabled: bool,
pub merge_queue_entry: Option<MergeQueueEntry>,
#[arguments(first: 20)]
pub labels: Option<LabelConnection>,
pub milestone: Option<MilestoneName>,
pub viewer_can_react: bool,
pub viewer_can_label: bool,
pub viewer_can_assign: bool,
pub reaction_groups: Option<Vec<crate::api::edit::WireReactionGroup>>,
#[arguments(first: 10)]
pub assignees: crate::api::browse::Assignees,
pub head_ref: Option<RefId>,
pub viewer_can_delete_head_ref: bool,
pub locked: bool,
pub active_lock_reason: Option<crate::api::timeline::LockReason>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Ref")]
pub struct RefId {
pub id: cynic::Id,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct AutoMergeRequest {
pub enabled_by: Option<Actor>,
pub merge_method: crate::api::change::MergeMethod,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct MergeQueueEntry {
pub position: i32,
pub state: crate::api::model::QueueState,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct Label {
pub name: String,
pub color: String,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct BehindVariables {
pub owner: String,
pub name: String,
pub base: String,
pub head: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "BehindVariables")]
pub struct BehindQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryBehind>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "BehindVariables")]
pub struct RepositoryBehind {
#[arguments(qualifiedName: $base)]
#[cynic(rename = "ref")]
pub base: Option<RefCompare>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Ref", variables = "BehindVariables")]
pub struct RefCompare {
#[arguments(headRef: $head)]
pub compare: Option<Behind>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Comparison")]
pub struct Behind {
pub behind_by: i32,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "PageVariables")]
pub struct PrFilesQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryWithPrFiles>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "PageVariables")]
pub struct RepositoryWithPrFiles {
#[arguments(number: $number)]
pub pull_request: Option<PrFiles>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest", variables = "PageVariables")]
pub struct PrFiles {
pub id: cynic::Id,
#[arguments(first: 100, after: $after)]
pub files: Option<PrChangedFiles>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestChangedFileConnection")]
pub struct PrChangedFiles {
pub page_info: PageInfo,
pub nodes: Option<Vec<Option<PrChangedFile>>>,
}
#[derive(cynic::QueryFragment, Debug)]
pub struct PageInfo {
pub has_next_page: bool,
pub end_cursor: Option<String>,
}
impl PageInfo {
pub fn next(self) -> Option<String> {
self.end_cursor.filter(|_| self.has_next_page)
}
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestChangedFile")]
pub struct PrChangedFile {
pub path: String,
pub viewer_viewed_state: ViewedState,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct ViewedVariables {
pub pull_request_id: cynic::Id,
pub path: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "ViewedVariables")]
pub struct MarkFileAsViewed {
#[arguments(input: { pullRequestId: $pull_request_id, path: $path })]
pub mark_file_as_viewed: Option<MarkFileAsViewedPayload>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "ViewedVariables")]
pub struct UnmarkFileAsViewed {
#[arguments(input: { pullRequestId: $pull_request_id, path: $path })]
pub unmark_file_as_viewed: Option<UnmarkFileAsViewedPayload>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "PageVariables")]
pub struct ThreadsQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryWithThreads>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "PageVariables")]
pub struct RepositoryWithThreads {
#[arguments(number: $number)]
pub pull_request: Option<PrThreads>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest", variables = "PageVariables")]
pub struct PrThreads {
#[arguments(first: 100, after: $after)]
pub review_threads: ThreadConnection,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReviewThreadConnection")]
pub struct ThreadConnection {
pub page_info: PageInfo,
pub nodes: Option<Vec<Option<ReviewThread>>>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReviewThread")]
pub struct ReviewThread {
pub id: cynic::Id,
pub path: String,
pub diff_side: Side,
pub start_diff_side: Option<Side>,
pub line: Option<i32>,
pub start_line: Option<i32>,
pub original_line: Option<i32>,
pub original_start_line: Option<i32>,
pub is_outdated: bool,
pub is_resolved: bool,
pub subject_type: ThreadSubjectType,
pub viewer_can_reply: bool,
pub viewer_can_resolve: bool,
pub viewer_can_unresolve: bool,
#[arguments(first: 1)]
#[cynic(rename = "comments", alias)]
pub first_comment: FirstCommentConnection,
#[arguments(last: 99)]
pub comments: ReviewCommentConnection,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReviewComment")]
pub struct ReviewComment {
pub id: cynic::Id,
pub author: Option<Actor>,
pub body: String,
pub created_at: DateTime,
pub url: Uri,
pub original_commit: Option<CommitOid>,
pub state: ReviewCommentState,
pub viewer_can_update: bool,
pub viewer_can_delete: bool,
pub viewer_can_react: bool,
pub reaction_groups: Option<Vec<crate::api::edit::WireReactionGroup>>,
pub pull_request_review: Option<ReviewDatabaseId>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReviewComment")]
pub struct FirstComment {
#[cynic(spread)]
pub comment: ReviewComment,
pub diff_hunk: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReview")]
pub struct ReviewDatabaseId {
pub full_database_id: Option<BigInt>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Commit")]
pub struct CommitOid {
pub oid: GitObjectId,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReview")]
pub struct PendingReview {
pub id: cynic::Id,
pub commit: Option<CommitOid>,
pub comments: ReviewCommentCount,
}
#[derive(cynic::Enum, Debug, Clone, Copy, PartialEq, Eq)]
#[cynic(graphql_type = "PullRequestReviewCommentState")]
pub enum ReviewCommentState {
Pending,
Submitted,
}
#[derive(cynic::Enum, Debug, Clone, Copy, PartialEq, Eq)]
#[cynic(graphql_type = "PullRequestReviewThreadSubjectType")]
pub enum ThreadSubjectType {
File,
Line,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "NumberVariables")]
pub struct PendingReviewQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryWithPendingReview>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "NumberVariables")]
pub struct RepositoryWithPendingReview {
#[arguments(number: $number)]
pub pull_request: Option<PrPendingReview>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest")]
pub struct PrPendingReview {
pub id: cynic::Id,
#[arguments(states: [PENDING], first: 1)]
pub reviews: Option<PendingReviewConnection>,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct StartReviewVariables {
pub pull_request_id: cynic::Id,
pub commit: GitObjectId,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "StartReviewVariables")]
pub struct StartReview {
#[arguments(input: { pullRequestId: $pull_request_id, commitOID: $commit })]
pub add_pull_request_review: Option<StartReviewPayload>,
}
#[derive(cynic::InputObject, Debug)]
#[cynic(
graphql_type = "AddPullRequestReviewThreadInput",
rename_all = "camelCase"
)]
pub struct AddThreadInput {
pub pull_request_review_id: Option<cynic::Id>,
pub path: Option<String>,
pub body: String,
#[cynic(skip_serializing_if = "Option::is_none")]
pub line: Option<i32>,
#[cynic(skip_serializing_if = "Option::is_none")]
pub side: Option<Side>,
#[cynic(skip_serializing_if = "Option::is_none")]
pub start_line: Option<i32>,
#[cynic(skip_serializing_if = "Option::is_none")]
pub start_side: Option<Side>,
pub subject_type: Option<ThreadSubjectType>,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct AddThreadVariables {
pub input: AddThreadInput,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "AddThreadVariables")]
pub struct AddThread {
#[arguments(input: $input)]
pub add_pull_request_review_thread: Option<ThreadPayload>,
}
#[derive(cynic::Enum, Debug, Clone, Copy, PartialEq, Eq)]
#[cynic(graphql_type = "PullRequestReviewEvent")]
pub enum ReviewEvent {
Approve,
Comment,
Dismiss,
RequestChanges,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct SubmitReviewVariables {
pub review_id: cynic::Id,
pub event: ReviewEvent,
pub body: Option<String>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "SubmitReviewVariables")]
pub struct SubmitReview {
#[arguments(input: { pullRequestReviewId: $review_id, event: $event, body: $body })]
pub submit_pull_request_review: Option<SubmitReviewPayload>,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct ReplyVariables {
pub thread_id: cynic::Id,
pub body: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "ReplyVariables")]
pub struct Reply {
#[arguments(input: { pullRequestReviewThreadId: $thread_id, body: $body })]
pub add_pull_request_review_thread_reply: Option<ReplyPayload>,
}
fragments! {
comment: Option<CommentId>;
ReplyPayload = "AddPullRequestReviewThreadReplyPayload",
}
#[derive(cynic::QueryVariables, Debug)]
pub struct ThreadIdVariables {
pub thread_id: cynic::Id,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "ThreadIdVariables")]
pub struct Resolve {
#[arguments(input: { threadId: $thread_id })]
pub resolve_review_thread: Option<ResolvePayload>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "ThreadIdVariables")]
pub struct Unresolve {
#[arguments(input: { threadId: $thread_id })]
pub unresolve_review_thread: Option<UnresolvePayload>,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct LastReviewVariables {
pub owner: String,
pub name: String,
pub number: i32,
pub login: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "LastReviewVariables")]
pub struct LastReviewQuery {
#[arguments(owner: $owner, name: $name)]
pub repository: Option<RepositoryWithReviews>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Repository", variables = "LastReviewVariables")]
pub struct RepositoryWithReviews {
#[arguments(number: $number)]
pub pull_request: Option<PrReviews>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequest", variables = "LastReviewVariables")]
pub struct PrReviews {
#[arguments(author: $login, last: 20)]
pub reviews: Option<ReviewCommitConnection>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PullRequestReview")]
pub struct ReviewCommit {
pub state: ReviewState,
pub commit: Option<CommitOid>,
}