Skip to main content

github_bot_sdk/events/
github_events.rs

1//! GitHub-specific event structures and types.
2//!
3//! This module defines typed structures for different GitHub webhook event types
4//! including pull requests, issues, pushes, check runs, and check suites.
5
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9use crate::client::{Issue, PullRequest, Repository};
10
11// ============================================================================
12// Pull Request Events
13// ============================================================================
14
15/// Pull request event with action and details.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct PullRequestEvent {
18    /// Action that triggered this event
19    pub action: PullRequestAction,
20
21    /// Pull request number
22    pub number: u32,
23
24    /// Pull request details
25    pub pull_request: PullRequest,
26
27    /// Repository information
28    pub repository: Repository,
29
30    /// User who triggered the event
31    pub sender: EventUser,
32}
33
34/// Actions that can occur on pull requests.
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36#[serde(rename_all = "snake_case")]
37pub enum PullRequestAction {
38    Opened,
39    Closed,
40    Reopened,
41    Synchronize,
42    Edited,
43    Assigned,
44    Unassigned,
45    ReviewRequested,
46    ReviewRequestRemoved,
47    Labeled,
48    Unlabeled,
49    ReadyForReview,
50    ConvertedToDraft,
51}
52
53impl fmt::Display for PullRequestAction {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        let s = match self {
56            Self::Opened => "opened",
57            Self::Closed => "closed",
58            Self::Reopened => "reopened",
59            Self::Synchronize => "synchronize",
60            Self::Edited => "edited",
61            Self::Assigned => "assigned",
62            Self::Unassigned => "unassigned",
63            Self::ReviewRequested => "review_requested",
64            Self::ReviewRequestRemoved => "review_request_removed",
65            Self::Labeled => "labeled",
66            Self::Unlabeled => "unlabeled",
67            Self::ReadyForReview => "ready_for_review",
68            Self::ConvertedToDraft => "converted_to_draft",
69        };
70        write!(f, "{}", s)
71    }
72}
73
74// ============================================================================
75// Issue Events
76// ============================================================================
77
78/// Issue event with action and details.
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct IssueEvent {
81    /// Action that triggered this event
82    pub action: IssueAction,
83
84    /// Issue details
85    pub issue: Issue,
86
87    /// Repository information
88    pub repository: Repository,
89
90    /// User who triggered the event
91    pub sender: EventUser,
92}
93
94/// Actions that can occur on issues.
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96#[serde(rename_all = "snake_case")]
97pub enum IssueAction {
98    Opened,
99    Closed,
100    Reopened,
101    Edited,
102    Assigned,
103    Unassigned,
104    Labeled,
105    Unlabeled,
106    Transferred,
107    Pinned,
108    Unpinned,
109}
110
111impl fmt::Display for IssueAction {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        let s = match self {
114            Self::Opened => "opened",
115            Self::Closed => "closed",
116            Self::Reopened => "reopened",
117            Self::Edited => "edited",
118            Self::Assigned => "assigned",
119            Self::Unassigned => "unassigned",
120            Self::Labeled => "labeled",
121            Self::Unlabeled => "unlabeled",
122            Self::Transferred => "transferred",
123            Self::Pinned => "pinned",
124            Self::Unpinned => "unpinned",
125        };
126        write!(f, "{}", s)
127    }
128}
129
130// ============================================================================
131// Push Events
132// ============================================================================
133
134/// Push event with commit information.
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct PushEvent {
137    /// Git ref that was pushed (e.g., "refs/heads/main")
138    #[serde(rename = "ref")]
139    pub ref_name: String,
140
141    /// Commit SHA before the push
142    pub before: String,
143
144    /// Commit SHA after the push
145    pub after: String,
146
147    /// Whether this push created the ref
148    pub created: bool,
149
150    /// Whether this push deleted the ref
151    pub deleted: bool,
152
153    /// Whether this was a force push
154    pub forced: bool,
155
156    /// Commits included in the push
157    pub commits: Vec<Commit>,
158
159    /// The most recent commit
160    pub head_commit: Option<Commit>,
161
162    /// Repository information
163    pub repository: Repository,
164
165    /// User who triggered the event
166    pub sender: EventUser,
167}
168
169/// Commit information from a push event.
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct Commit {
172    /// Commit SHA
173    pub id: String,
174
175    /// Commit message
176    pub message: String,
177
178    /// Commit timestamp
179    pub timestamp: String,
180
181    /// Commit author
182    pub author: CommitAuthor,
183
184    /// Commit committer
185    pub committer: CommitAuthor,
186}
187
188/// Author or committer information in a commit.
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct CommitAuthor {
191    /// Name
192    pub name: String,
193
194    /// Email address
195    pub email: String,
196
197    /// GitHub username (if available)
198    pub username: Option<String>,
199}
200
201// ============================================================================
202// Check Run Events
203// ============================================================================
204
205/// Check run event.
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct CheckRunEvent {
208    /// Action that triggered this event
209    pub action: CheckRunAction,
210
211    /// Check run details
212    pub check_run: CheckRun,
213
214    /// Repository information
215    pub repository: Repository,
216
217    /// User who triggered the event
218    pub sender: EventUser,
219}
220
221/// Actions that can occur on check runs.
222#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
223#[serde(rename_all = "snake_case")]
224pub enum CheckRunAction {
225    Created,
226    Completed,
227    Rerequested,
228    RequestedAction,
229}
230
231/// Check run details.
232#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct CheckRun {
234    /// Check run ID
235    pub id: u64,
236
237    /// Check run name
238    pub name: String,
239
240    /// Check run status
241    pub status: String,
242
243    /// Check run conclusion (if completed)
244    pub conclusion: Option<String>,
245}
246
247// ============================================================================
248// Check Suite Events
249// ============================================================================
250
251/// Check suite event.
252#[derive(Debug, Clone, Serialize, Deserialize)]
253pub struct CheckSuiteEvent {
254    /// Action that triggered this event
255    pub action: CheckSuiteAction,
256
257    /// Check suite details
258    pub check_suite: CheckSuite,
259
260    /// Repository information
261    pub repository: Repository,
262
263    /// User who triggered the event
264    pub sender: EventUser,
265}
266
267/// Actions that can occur on check suites.
268#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
269#[serde(rename_all = "snake_case")]
270pub enum CheckSuiteAction {
271    Completed,
272    Requested,
273    Rerequested,
274}
275
276/// Check suite details.
277#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct CheckSuite {
279    /// Check suite ID
280    pub id: u64,
281
282    /// Check suite status
283    pub status: String,
284
285    /// Check suite conclusion (if completed)
286    pub conclusion: Option<String>,
287}
288
289// ============================================================================
290// Shared Types
291// ============================================================================
292
293/// User information in event payloads.
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct EventUser {
296    /// User ID
297    pub id: u64,
298
299    /// Username
300    pub login: String,
301
302    /// User type (User, Bot, Organization)
303    #[serde(rename = "type")]
304    pub user_type: String,
305}
306
307#[cfg(test)]
308#[path = "github_events_tests.rs"]
309mod tests;