1use std::fmt::Display;
2
3use crate::{git::Commit, BranchName, ForgeAlias, RepoAlias};
5use serde_json::json;
6
7use super::graph::Log;
8
9#[derive(Clone, Debug, Hash, PartialEq, Eq)]
10pub enum UserNotification {
11 CICheckFailed {
12 forge_alias: ForgeAlias,
13 repo_alias: RepoAlias,
14 commit: Commit,
15 log: Log,
16 },
17 RepoConfigLoadFailure {
18 forge_alias: ForgeAlias,
19 repo_alias: RepoAlias,
20 reason: String,
21 },
22 WebhookRegistration {
23 forge_alias: ForgeAlias,
24 repo_alias: RepoAlias,
25 reason: String,
26 },
27 DevNotBasedOnMain {
28 forge_alias: ForgeAlias,
29 repo_alias: RepoAlias,
30 dev_branch: BranchName,
31 main_branch: BranchName,
32 dev_commit: Commit,
33 main_commit: Commit,
34 log: Log,
35 },
36}
37impl UserNotification {
38 #[must_use]
39 pub fn as_json(&self, timestamp: time::OffsetDateTime) -> serde_json::Value {
40 let timestamp = timestamp.unix_timestamp();
41 match self {
42 Self::CICheckFailed {
43 forge_alias,
44 repo_alias,
45 commit,
46 log,
47 } => json!({
48 "type": "cicheck.failed",
49 "timestamp": timestamp,
50 "data": {
51 "forge_alias": forge_alias,
52 "repo_alias": repo_alias,
53 "commit": {
54 "sha": commit.sha(),
55 "message": commit.message()
56 },
57 "log": **log
58 }
59 }),
60 Self::RepoConfigLoadFailure {
61 forge_alias,
62 repo_alias,
63 reason,
64 } => json!({
65 "type": "config.load.failed",
66 "timestamp": timestamp,
67 "data": {
68 "forge_alias": forge_alias,
69 "repo_alias": repo_alias,
70 "reason": reason,
71 }
72 }),
73 Self::WebhookRegistration {
74 forge_alias,
75 repo_alias,
76 reason,
77 } => json!({
78 "type": "webhook.registration.failed",
79 "timestamp": timestamp,
80 "data": {
81 "forge_alias": forge_alias,
82 "repo_alias": repo_alias,
83 "reason": reason,
84 }
85 }),
86 Self::DevNotBasedOnMain {
87 forge_alias,
88 repo_alias,
89 dev_branch,
90 main_branch,
91 dev_commit,
92 main_commit,
93 log,
94 } => json!({
95 "type": "branch.dev.not-on-main",
96 "timestamp": timestamp,
97 "data": {
98 "forge_alias": forge_alias,
99 "repo_alias": repo_alias,
100 "branches": {
101 "dev": dev_branch,
102 "main": main_branch
103 },
104 "commits": {
105 "dev": {
106 "sha": dev_commit.sha(),
107 "message": dev_commit.message()
108 },
109 "main": {
110 "sha": main_commit.sha(),
111 "message": main_commit.message()
112 }
113 },
114 "log": **log
115 }
116 }),
117 }
118 }
119
120 #[must_use]
121 pub fn aliases(&self) -> (ForgeAlias, RepoAlias) {
122 match self {
123 Self::CICheckFailed {
124 forge_alias,
125 repo_alias,
126 ..
127 }
128 | Self::RepoConfigLoadFailure {
129 forge_alias,
130 repo_alias,
131 ..
132 }
133 | Self::WebhookRegistration {
134 forge_alias,
135 repo_alias,
136 ..
137 }
138 | Self::DevNotBasedOnMain {
139 forge_alias,
140 repo_alias,
141 ..
142 } => (forge_alias.clone(), repo_alias.clone()),
143 }
144 }
145}
146impl Display for UserNotification {
147 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148 let message = match self {
149 Self::CICheckFailed { commit, .. } => format!("CI Check Failed [{commit}]"),
150 Self::RepoConfigLoadFailure { reason, .. } => {
151 format!("Failed to load repo config: {reason}")
152 }
153 Self::WebhookRegistration { reason, .. } => {
154 format!("Failed to register webhook: {reason}")
155 }
156 Self::DevNotBasedOnMain {
157 dev_branch,
158 main_branch,
159 ..
160 } => format!("{dev_branch} not based on {main_branch}"),
161 };
162 write!(f, "{message}")
163 }
164}