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, skip_serializing_if = "Option::is_none")]
99 pub repository: Option<JsonValue>,
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub repo: Option<JsonValue>,
102 pub raw: JsonValue,
103}
104
105#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
106pub struct GitHubIssuesEventPayload {
107 #[serde(flatten)]
108 pub common: GitHubEventCommon,
109 pub issue: JsonValue,
110}
111
112#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
113pub struct GitHubPullRequestEventPayload {
114 #[serde(flatten)]
115 pub common: GitHubEventCommon,
116 pub pull_request: JsonValue,
117}
118
119#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
120pub struct GitHubIssueCommentEventPayload {
121 #[serde(flatten)]
122 pub common: GitHubEventCommon,
123 pub issue: JsonValue,
124 pub comment: JsonValue,
125}
126
127#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
128pub struct GitHubPullRequestReviewEventPayload {
129 #[serde(flatten)]
130 pub common: GitHubEventCommon,
131 pub pull_request: JsonValue,
132 pub review: JsonValue,
133}
134
135#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
136pub struct GitHubPushEventPayload {
137 #[serde(flatten)]
138 pub common: GitHubEventCommon,
139 #[serde(default)]
140 pub commits: Vec<JsonValue>,
141 #[serde(default, skip_serializing_if = "Option::is_none")]
142 pub distinct_size: Option<i64>,
143}
144
145#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
146pub struct GitHubWorkflowRunEventPayload {
147 #[serde(flatten)]
148 pub common: GitHubEventCommon,
149 pub workflow_run: JsonValue,
150}
151
152#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
153pub struct GitHubDeploymentStatusEventPayload {
154 #[serde(flatten)]
155 pub common: GitHubEventCommon,
156 pub deployment_status: JsonValue,
157 pub deployment: JsonValue,
158}
159
160#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
161pub struct GitHubCheckRunEventPayload {
162 #[serde(flatten)]
163 pub common: GitHubEventCommon,
164 pub check_run: JsonValue,
165}
166
167#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
168pub struct GitHubCheckSuiteEventPayload {
169 #[serde(flatten)]
170 pub common: GitHubEventCommon,
171 pub check_suite: JsonValue,
172 #[serde(default, skip_serializing_if = "Option::is_none")]
173 pub check_suite_id: Option<i64>,
174 #[serde(default, skip_serializing_if = "Option::is_none")]
175 pub pull_request_number: Option<i64>,
176 #[serde(default, skip_serializing_if = "Option::is_none")]
177 pub head_sha: Option<String>,
178 #[serde(default, skip_serializing_if = "Option::is_none")]
179 pub head_ref: Option<String>,
180 #[serde(default, skip_serializing_if = "Option::is_none")]
181 pub base_ref: Option<String>,
182 #[serde(default, skip_serializing_if = "Option::is_none")]
183 pub status: Option<String>,
184 #[serde(default, skip_serializing_if = "Option::is_none")]
185 pub conclusion: Option<String>,
186}
187
188#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
189pub struct GitHubStatusEventPayload {
190 #[serde(flatten)]
191 pub common: GitHubEventCommon,
192 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub commit_status: Option<JsonValue>,
194 #[serde(default, skip_serializing_if = "Option::is_none")]
195 pub status_id: Option<i64>,
196 #[serde(default, skip_serializing_if = "Option::is_none")]
197 pub head_sha: Option<String>,
198 #[serde(default, skip_serializing_if = "Option::is_none")]
199 pub head_ref: Option<String>,
200 #[serde(default, skip_serializing_if = "Option::is_none")]
201 pub base_ref: Option<String>,
202 #[serde(default, skip_serializing_if = "Option::is_none")]
203 pub state: Option<String>,
204 #[serde(default, skip_serializing_if = "Option::is_none")]
205 pub context: Option<String>,
206 #[serde(default, skip_serializing_if = "Option::is_none")]
207 pub target_url: Option<String>,
208}
209
210#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
211pub struct GitHubMergeGroupEventPayload {
212 #[serde(flatten)]
213 pub common: GitHubEventCommon,
214 pub merge_group: JsonValue,
215 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub merge_group_id: Option<JsonValue>,
217 #[serde(default, skip_serializing_if = "Option::is_none")]
218 pub head_sha: Option<String>,
219 #[serde(default, skip_serializing_if = "Option::is_none")]
220 pub head_ref: Option<String>,
221 #[serde(default, skip_serializing_if = "Option::is_none")]
222 pub base_sha: Option<String>,
223 #[serde(default, skip_serializing_if = "Option::is_none")]
224 pub base_ref: Option<String>,
225 #[serde(default)]
226 pub pull_requests: Vec<JsonValue>,
227 #[serde(default)]
228 pub pull_request_numbers: Vec<i64>,
229}
230
231#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
232pub struct GitHubInstallationEventPayload {
233 #[serde(flatten)]
234 pub common: GitHubEventCommon,
235 #[serde(default, skip_serializing_if = "Option::is_none")]
236 pub installation: Option<JsonValue>,
237 #[serde(default, skip_serializing_if = "Option::is_none")]
238 pub account: Option<JsonValue>,
239 #[serde(default, skip_serializing_if = "Option::is_none")]
240 pub installation_state: Option<String>,
241 #[serde(default, skip_serializing_if = "Option::is_none")]
242 pub suspended: Option<bool>,
243 #[serde(default, skip_serializing_if = "Option::is_none")]
244 pub revoked: Option<bool>,
245 #[serde(default)]
246 pub repositories: Vec<JsonValue>,
247}
248
249#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
250pub struct GitHubInstallationRepositoriesEventPayload {
251 #[serde(flatten)]
252 pub common: GitHubEventCommon,
253 #[serde(default, skip_serializing_if = "Option::is_none")]
254 pub installation: Option<JsonValue>,
255 #[serde(default, skip_serializing_if = "Option::is_none")]
256 pub account: Option<JsonValue>,
257 #[serde(default, skip_serializing_if = "Option::is_none")]
258 pub installation_state: Option<String>,
259 #[serde(default, skip_serializing_if = "Option::is_none")]
260 pub suspended: Option<bool>,
261 #[serde(default, skip_serializing_if = "Option::is_none")]
262 pub revoked: Option<bool>,
263 #[serde(default, skip_serializing_if = "Option::is_none")]
264 pub repository_selection: Option<String>,
265 #[serde(default)]
266 pub repositories_added: Vec<JsonValue>,
267 #[serde(default)]
268 pub repositories_removed: Vec<JsonValue>,
269}
270
271#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
272#[serde(untagged)]
273pub enum GitHubEventPayload {
274 Issues(GitHubIssuesEventPayload),
275 PullRequest(GitHubPullRequestEventPayload),
276 IssueComment(GitHubIssueCommentEventPayload),
277 PullRequestReview(GitHubPullRequestReviewEventPayload),
278 Push(GitHubPushEventPayload),
279 WorkflowRun(GitHubWorkflowRunEventPayload),
280 DeploymentStatus(GitHubDeploymentStatusEventPayload),
281 CheckRun(GitHubCheckRunEventPayload),
282 CheckSuite(GitHubCheckSuiteEventPayload),
283 Status(GitHubStatusEventPayload),
284 MergeGroup(GitHubMergeGroupEventPayload),
285 Installation(GitHubInstallationEventPayload),
286 InstallationRepositories(GitHubInstallationRepositoriesEventPayload),
287 Other(GitHubEventCommon),
288}
289
290impl<'de> Deserialize<'de> for GitHubEventPayload {
291 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
292 where
293 D: Deserializer<'de>,
294 {
295 let value = JsonValue::deserialize(deserializer)?;
296 let kind = value
297 .get("event")
298 .and_then(JsonValue::as_str)
299 .unwrap_or("")
300 .to_string();
301 let payload = match kind.as_str() {
302 "issues" => GitHubEventPayload::Issues(
303 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
304 ),
305 "pull_request" => GitHubEventPayload::PullRequest(
306 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
307 ),
308 "issue_comment" => GitHubEventPayload::IssueComment(
309 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
310 ),
311 "pull_request_review" => GitHubEventPayload::PullRequestReview(
312 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
313 ),
314 "push" => GitHubEventPayload::Push(
315 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
316 ),
317 "workflow_run" => GitHubEventPayload::WorkflowRun(
318 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
319 ),
320 "deployment_status" => GitHubEventPayload::DeploymentStatus(
321 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
322 ),
323 "check_run" => GitHubEventPayload::CheckRun(
324 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
325 ),
326 "check_suite" => GitHubEventPayload::CheckSuite(
327 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
328 ),
329 "status" => GitHubEventPayload::Status(
330 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
331 ),
332 "merge_group" => GitHubEventPayload::MergeGroup(
333 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
334 ),
335 "installation" => GitHubEventPayload::Installation(
336 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
337 ),
338 "installation_repositories" => GitHubEventPayload::InstallationRepositories(
339 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
340 ),
341 _ => GitHubEventPayload::Other(
342 serde_json::from_value(value).map_err(serde::de::Error::custom)?,
343 ),
344 };
345 Ok(payload)
346 }
347}