1use std::collections::BTreeMap;
13
14use serde::{Deserialize, Deserializer, Serialize};
15use serde_json::Value as JsonValue;
16
17#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
18pub struct GitForgeRepositoryRef {
19 pub provider: String,
20 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub full_name: Option<String>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub id: Option<String>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub web_url: Option<String>,
26}
27
28#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29pub struct GitForgePullRequestRef {
30 pub number: i64,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub id: Option<String>,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub title: Option<String>,
35 #[serde(default, skip_serializing_if = "Option::is_none")]
36 pub author: Option<String>,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub web_url: Option<String>,
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub head_ref: Option<String>,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub head_sha: Option<String>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub base_ref: Option<String>,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub base_sha: Option<String>,
47 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub state: Option<String>,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub draft: Option<bool>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub merged: Option<bool>,
53}
54
55#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
56pub struct GitForgeWritebackTarget {
57 pub provider: String,
58 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub repository_full_name: Option<String>,
60 #[serde(default, skip_serializing_if = "Option::is_none")]
61 pub repository_id: Option<String>,
62 pub pull_request_number: i64,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub web_url: Option<String>,
65}
66
67#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
68pub struct GitForgePullRequestEvent {
69 pub topic: String,
70 pub event: String,
71 pub kind: String,
72 pub provider: String,
73 pub lifecycle: String,
74 pub repository: GitForgeRepositoryRef,
75 pub pull_request: GitForgePullRequestRef,
76 pub writeback: GitForgeWritebackTarget,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
78 pub delivery_id: Option<String>,
79 #[serde(default, skip_serializing_if = "Option::is_none")]
80 pub signature_status: Option<JsonValue>,
81 #[serde(default)]
82 pub provider_metadata: BTreeMap<String, JsonValue>,
83 pub raw_payload: JsonValue,
84}
85
86#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
87pub struct GitHubEventCommon {
88 pub event: String,
89 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub action: Option<String>,
91 #[serde(default, skip_serializing_if = "Option::is_none")]
92 pub delivery_id: Option<String>,
93 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub installation_id: Option<i64>,
95 #[serde(default, skip_serializing_if = "Option::is_none")]
96 pub topic: Option<String>,
97 #[serde(default)]
98 pub reaction_topics: Vec<String>,
99 #[serde(default, skip_serializing_if = "Option::is_none")]
100 pub repository: Option<JsonValue>,
101 #[serde(default, skip_serializing_if = "Option::is_none")]
102 pub repo: Option<JsonValue>,
103 pub raw: JsonValue,
104}
105
106#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
107pub struct GitHubIssuesEventPayload {
108 #[serde(flatten)]
109 pub common: GitHubEventCommon,
110 pub issue: JsonValue,
111}
112
113#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
114pub struct GitHubPullRequestEventPayload {
115 #[serde(flatten)]
116 pub common: GitHubEventCommon,
117 pub pull_request: JsonValue,
118}
119
120#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
121pub struct GitHubIssueCommentEventPayload {
122 #[serde(flatten)]
123 pub common: GitHubEventCommon,
124 pub issue: JsonValue,
125 pub comment: JsonValue,
126}
127
128#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
129pub struct GitHubPullRequestReviewEventPayload {
130 #[serde(flatten)]
131 pub common: GitHubEventCommon,
132 pub pull_request: JsonValue,
133 pub review: JsonValue,
134}
135
136#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
137pub struct GitHubPushEventPayload {
138 #[serde(flatten)]
139 pub common: GitHubEventCommon,
140 #[serde(default)]
141 pub commits: Vec<JsonValue>,
142 #[serde(default, skip_serializing_if = "Option::is_none")]
143 pub distinct_size: Option<i64>,
144}
145
146#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
147pub struct GitHubWorkflowRunEventPayload {
148 #[serde(flatten)]
149 pub common: GitHubEventCommon,
150 pub workflow_run: JsonValue,
151}
152
153#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
154pub struct GitHubDeploymentStatusEventPayload {
155 #[serde(flatten)]
156 pub common: GitHubEventCommon,
157 pub deployment_status: JsonValue,
158 pub deployment: JsonValue,
159}
160
161#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
162pub struct GitHubCheckRunEventPayload {
163 #[serde(flatten)]
164 pub common: GitHubEventCommon,
165 pub check_run: JsonValue,
166}
167
168#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
169pub struct GitHubCheckSuiteEventPayload {
170 #[serde(flatten)]
171 pub common: GitHubEventCommon,
172 pub check_suite: JsonValue,
173 #[serde(default, skip_serializing_if = "Option::is_none")]
174 pub check_suite_id: Option<i64>,
175 #[serde(default, skip_serializing_if = "Option::is_none")]
176 pub pull_request_number: Option<i64>,
177 #[serde(default, skip_serializing_if = "Option::is_none")]
178 pub head_sha: Option<String>,
179 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub head_ref: Option<String>,
181 #[serde(default, skip_serializing_if = "Option::is_none")]
182 pub base_ref: Option<String>,
183 #[serde(default, skip_serializing_if = "Option::is_none")]
184 pub status: Option<String>,
185 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub conclusion: Option<String>,
187}
188
189#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
190pub struct GitHubStatusEventPayload {
191 #[serde(flatten)]
192 pub common: GitHubEventCommon,
193 #[serde(default, skip_serializing_if = "Option::is_none")]
194 pub commit_status: Option<JsonValue>,
195 #[serde(default, skip_serializing_if = "Option::is_none")]
196 pub status_id: Option<i64>,
197 #[serde(default, skip_serializing_if = "Option::is_none")]
198 pub head_sha: Option<String>,
199 #[serde(default, skip_serializing_if = "Option::is_none")]
200 pub head_ref: Option<String>,
201 #[serde(default, skip_serializing_if = "Option::is_none")]
202 pub base_ref: Option<String>,
203 #[serde(default, skip_serializing_if = "Option::is_none")]
204 pub state: Option<String>,
205 #[serde(default, skip_serializing_if = "Option::is_none")]
206 pub context: Option<String>,
207 #[serde(default, skip_serializing_if = "Option::is_none")]
208 pub target_url: Option<String>,
209}
210
211#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
212pub struct GitHubMergeGroupEventPayload {
213 #[serde(flatten)]
214 pub common: GitHubEventCommon,
215 pub merge_group: JsonValue,
216 #[serde(default, skip_serializing_if = "Option::is_none")]
217 pub merge_group_id: Option<JsonValue>,
218 #[serde(default, skip_serializing_if = "Option::is_none")]
219 pub head_sha: Option<String>,
220 #[serde(default, skip_serializing_if = "Option::is_none")]
221 pub head_ref: Option<String>,
222 #[serde(default, skip_serializing_if = "Option::is_none")]
223 pub base_sha: Option<String>,
224 #[serde(default, skip_serializing_if = "Option::is_none")]
225 pub base_ref: Option<String>,
226 #[serde(default)]
227 pub pull_requests: Vec<JsonValue>,
228 #[serde(default)]
229 pub pull_request_numbers: Vec<i64>,
230}
231
232#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
233pub struct GitHubInstallationEventPayload {
234 #[serde(flatten)]
235 pub common: GitHubEventCommon,
236 #[serde(default, skip_serializing_if = "Option::is_none")]
237 pub installation: Option<JsonValue>,
238 #[serde(default, skip_serializing_if = "Option::is_none")]
239 pub account: Option<JsonValue>,
240 #[serde(default, skip_serializing_if = "Option::is_none")]
241 pub installation_state: Option<String>,
242 #[serde(default, skip_serializing_if = "Option::is_none")]
243 pub suspended: Option<bool>,
244 #[serde(default, skip_serializing_if = "Option::is_none")]
245 pub revoked: Option<bool>,
246 #[serde(default)]
247 pub repositories: Vec<JsonValue>,
248}
249
250#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
251pub struct GitHubInstallationRepositoriesEventPayload {
252 #[serde(flatten)]
253 pub common: GitHubEventCommon,
254 #[serde(default, skip_serializing_if = "Option::is_none")]
255 pub installation: Option<JsonValue>,
256 #[serde(default, skip_serializing_if = "Option::is_none")]
257 pub account: Option<JsonValue>,
258 #[serde(default, skip_serializing_if = "Option::is_none")]
259 pub installation_state: Option<String>,
260 #[serde(default, skip_serializing_if = "Option::is_none")]
261 pub suspended: Option<bool>,
262 #[serde(default, skip_serializing_if = "Option::is_none")]
263 pub revoked: Option<bool>,
264 #[serde(default, skip_serializing_if = "Option::is_none")]
265 pub repository_selection: Option<String>,
266 #[serde(default)]
267 pub repositories_added: Vec<JsonValue>,
268 #[serde(default)]
269 pub repositories_removed: Vec<JsonValue>,
270}
271
272#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
273#[serde(untagged)]
274pub enum GitHubEventPayload {
275 Issues(GitHubIssuesEventPayload),
276 PullRequest(GitHubPullRequestEventPayload),
277 IssueComment(GitHubIssueCommentEventPayload),
278 PullRequestReview(GitHubPullRequestReviewEventPayload),
279 Push(GitHubPushEventPayload),
280 WorkflowRun(GitHubWorkflowRunEventPayload),
281 DeploymentStatus(GitHubDeploymentStatusEventPayload),
282 CheckRun(GitHubCheckRunEventPayload),
283 CheckSuite(GitHubCheckSuiteEventPayload),
284 Status(GitHubStatusEventPayload),
285 MergeGroup(GitHubMergeGroupEventPayload),
286 Installation(GitHubInstallationEventPayload),
287 InstallationRepositories(GitHubInstallationRepositoriesEventPayload),
288 Other(GitHubEventCommon),
289}
290
291impl<'de> Deserialize<'de> for GitHubEventPayload {
292 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
293 where
294 D: Deserializer<'de>,
295 {
296 let value = JsonValue::deserialize(deserializer)?;
297 let kind = value
298 .get("event")
299 .and_then(JsonValue::as_str)
300 .unwrap_or("")
301 .to_string();
302 let payload = match kind.as_str() {
303 "issues" => GitHubEventPayload::Issues(
304 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
305 ),
306 "pull_request" => GitHubEventPayload::PullRequest(
307 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
308 ),
309 "issue_comment" => GitHubEventPayload::IssueComment(
310 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
311 ),
312 "pull_request_review" => GitHubEventPayload::PullRequestReview(
313 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
314 ),
315 "push" => GitHubEventPayload::Push(
316 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
317 ),
318 "workflow_run" => GitHubEventPayload::WorkflowRun(
319 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
320 ),
321 "deployment_status" => GitHubEventPayload::DeploymentStatus(
322 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
323 ),
324 "check_run" => GitHubEventPayload::CheckRun(
325 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
326 ),
327 "check_suite" => GitHubEventPayload::CheckSuite(
328 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
329 ),
330 "status" => GitHubEventPayload::Status(
331 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
332 ),
333 "merge_group" => GitHubEventPayload::MergeGroup(
334 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
335 ),
336 "installation" => GitHubEventPayload::Installation(
337 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
338 ),
339 "installation_repositories" => GitHubEventPayload::InstallationRepositories(
340 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
341 ),
342 _ => GitHubEventPayload::Other(
343 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
344 ),
345 };
346 Ok(payload)
347 }
348}