a73x

src/event.rs

Ref:   Size: 3.8 KiB

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Author {
    pub name: String,
    pub email: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Event {
    pub timestamp: String,
    pub author: Author,
    pub action: Action,
    #[serde(default)]
    pub clock: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Action {
    #[serde(rename = "issue.open")]
    IssueOpen {
        title: String,
        body: String,
        #[serde(default, skip_serializing_if = "Option::is_none")]
        relates_to: Option<String>,
    },
    #[serde(rename = "issue.comment")]
    IssueComment {
        body: String,
    },
    #[serde(rename = "issue.close")]
    IssueClose {
        reason: Option<String>,
    },
    #[serde(rename = "issue.edit")]
    IssueEdit {
        title: Option<String>,
        body: Option<String>,
    },
    #[serde(rename = "issue.label")]
    IssueLabel {
        label: String,
    },
    #[serde(rename = "issue.unlabel")]
    IssueUnlabel {
        label: String,
    },
    #[serde(rename = "issue.assign")]
    IssueAssign {
        assignee: String,
    },
    #[serde(rename = "issue.unassign")]
    IssueUnassign {
        assignee: String,
    },
    #[serde(rename = "issue.reopen")]
    IssueReopen,
    #[serde(rename = "issue.commit_link")]
    IssueCommitLink {
        commit: String,
    },
    #[serde(rename = "patch.create", alias = "PatchCreate")]
    PatchCreate {
        title: String,
        body: String,
        base_ref: String,
        #[serde(alias = "head_commit")]
        branch: String,
        #[serde(default, skip_serializing_if = "Option::is_none")]
        fixes: Option<String>,
        commit: String,
        tree: String,
        /// Base branch tip OID at creation time (for merge detection).
        #[serde(default, skip_serializing_if = "Option::is_none")]
        base_commit: Option<String>,
    },
    #[serde(rename = "patch.revision")]
    PatchRevision {
        commit: String,
        tree: String,
        #[serde(default, skip_serializing_if = "Option::is_none")]
        body: Option<String>,
    },
    #[serde(rename = "patch.review")]
    PatchReview {
        verdict: ReviewVerdict,
        body: String,
        revision: u32,
    },
    #[serde(rename = "patch.comment")]
    PatchComment {
        body: String,
    },
    #[serde(rename = "patch.inline_comment")]
    PatchInlineComment {
        file: String,
        line: u32,
        body: String,
        revision: u32,
    },
    #[serde(rename = "patch.close")]
    PatchClose {
        reason: Option<String>,
    },
    #[serde(rename = "patch.merge")]
    PatchMerge,
    #[serde(rename = "collab.merge")]
    Merge,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
pub enum ReviewVerdict {
    Approve,
    RequestChanges,
    Comment,
    Reject,
}

impl ReviewVerdict {
    pub fn as_str(&self) -> &'static str {
        match self {
            ReviewVerdict::Approve => "approve",
            ReviewVerdict::RequestChanges => "request-changes",
            ReviewVerdict::Comment => "comment",
            ReviewVerdict::Reject => "reject",
        }
    }
}

impl std::fmt::Display for ReviewVerdict {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.as_str())
    }
}

impl std::str::FromStr for ReviewVerdict {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "approve" => Ok(ReviewVerdict::Approve),
            "request-changes" => Ok(ReviewVerdict::RequestChanges),
            "comment" => Ok(ReviewVerdict::Comment),
            "reject" => Ok(ReviewVerdict::Reject),
            other => Err(format!("unknown verdict: {}", other)),
        }
    }
}