automatons_github/resource/check_run/
mod.rs1use std::fmt::{Display, Formatter};
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Deserializer, Serialize};
5use url::Url;
6
7use crate::resource::{App, CheckSuite, Field, GitSha, MinimalCheckSuite, NodeId, PullRequest};
8use crate::{id, name};
9
10pub use self::conclusion::CheckRunConclusion;
11pub use self::output::{CheckRunOutput, CheckRunOutputSummary, CheckRunOutputTitle};
12pub use self::status::CheckRunStatus;
13
14mod conclusion;
15mod output;
16mod status;
17
18id!(
19 CheckRunId
24);
25
26name!(
27 CheckRunName
31);
32
33#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
38pub struct CheckRun {
39 id: CheckRunId,
40 node_id: NodeId,
41 name: CheckRunName,
42 head_sha: GitSha,
43 external_id: String,
44 url: Url,
45 html_url: Url,
46 details_url: Url,
47 status: CheckRunStatus,
48 conclusion: Option<CheckRunConclusion>,
49 started_at: DateTime<Utc>,
50 completed_at: Option<DateTime<Utc>>,
51 check_suite: Field<MinimalCheckSuite, CheckSuite>,
52 app: App,
53 pull_requests: Vec<PullRequest>,
54
55 #[serde(deserialize_with = "deserialize_output")]
56 output: Option<CheckRunOutput>,
57}
58
59impl CheckRun {
60 #[cfg_attr(feature = "tracing", tracing::instrument)]
62 pub fn id(&self) -> CheckRunId {
63 self.id
64 }
65
66 #[cfg_attr(feature = "tracing", tracing::instrument)]
68 pub fn node_id(&self) -> &NodeId {
69 &self.node_id
70 }
71
72 #[cfg_attr(feature = "tracing", tracing::instrument)]
74 pub fn name(&self) -> &CheckRunName {
75 &self.name
76 }
77
78 #[cfg_attr(feature = "tracing", tracing::instrument)]
80 pub fn head_sha(&self) -> &GitSha {
81 &self.head_sha
82 }
83
84 #[cfg_attr(feature = "tracing", tracing::instrument)]
86 pub fn external_id(&self) -> &str {
87 &self.external_id
88 }
89
90 #[cfg_attr(feature = "tracing", tracing::instrument)]
92 pub fn url(&self) -> &Url {
93 &self.url
94 }
95
96 #[cfg_attr(feature = "tracing", tracing::instrument)]
98 pub fn html_url(&self) -> &Url {
99 &self.html_url
100 }
101
102 #[cfg_attr(feature = "tracing", tracing::instrument)]
104 pub fn details_url(&self) -> &Url {
105 &self.details_url
106 }
107
108 #[cfg_attr(feature = "tracing", tracing::instrument)]
110 pub fn status(&self) -> CheckRunStatus {
111 self.status
112 }
113
114 #[cfg_attr(feature = "tracing", tracing::instrument)]
116 pub fn conclusion(&self) -> Option<CheckRunConclusion> {
117 self.conclusion
118 }
119
120 #[cfg_attr(feature = "tracing", tracing::instrument)]
122 pub fn started_at(&self) -> &DateTime<Utc> {
123 &self.started_at
124 }
125
126 #[cfg_attr(feature = "tracing", tracing::instrument)]
128 pub fn completed_at(&self) -> &Option<DateTime<Utc>> {
129 &self.completed_at
130 }
131
132 #[cfg_attr(feature = "tracing", tracing::instrument)]
134 pub fn output(&self) -> &Option<CheckRunOutput> {
135 &self.output
136 }
137
138 #[cfg_attr(feature = "tracing", tracing::instrument)]
140 pub fn check_suite(&self) -> &Field<MinimalCheckSuite, CheckSuite> {
141 &self.check_suite
142 }
143
144 #[cfg_attr(feature = "tracing", tracing::instrument)]
146 pub fn app(&self) -> &App {
147 &self.app
148 }
149
150 #[cfg_attr(feature = "tracing", tracing::instrument)]
152 pub fn pull_requests(&self) -> &Vec<PullRequest> {
153 &self.pull_requests
154 }
155}
156
157impl Display for CheckRun {
158 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
159 write!(f, "{}", self.name)
160 }
161}
162
163fn deserialize_output<'de, D>(deserializer: D) -> Result<Option<CheckRunOutput>, D::Error>
164where
165 D: Deserializer<'de>,
166{
167 let json = serde_json::Value::deserialize(deserializer)?;
168
169 let title_field = match json.get("title") {
170 Some(title) => title,
171 None => return Ok(None),
172 };
173
174 if title_field.is_null() {
176 return Ok(None);
177 }
178
179 let output = serde_json::from_value(json).expect("failed to deserialize check run output");
181
182 Ok(Some(output))
183}
184
185#[cfg(test)]
186mod tests {
187 use super::CheckRun;
188
189 #[test]
190 fn trait_deserialize() {
191 let check_run: CheckRun = serde_json::from_str(include_str!(
192 "../../../tests/fixtures/resource/check_run.json"
193 ))
194 .unwrap();
195
196 assert_eq!(&None, check_run.output());
197 }
198
199 #[test]
200 fn trait_send() {
201 fn assert_send<T: Send>() {}
202 assert_send::<CheckRun>();
203 }
204
205 #[test]
206 fn trait_sync() {
207 fn assert_sync<T: Sync>() {}
208 assert_sync::<CheckRun>();
209 }
210}