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