hubcaps_ex/
checks.rs

1//! Checks interface
2// see: https://developer.github.com/v3/checks/suites/
3use serde::{Deserialize, Serialize};
4
5use self::super::{AuthenticationConstraint, Future, Github, MediaType};
6
7pub struct CheckRuns {
8    github: Github,
9    owner: String,
10    repo: String,
11}
12
13impl<'a> CheckRuns {
14    #[doc(hidden)]
15    pub(crate) fn new<O, R>(github: Github, owner: O, repo: R) -> Self
16    where
17        O: Into<String>,
18        R: Into<String>,
19    {
20        CheckRuns {
21            github,
22            owner: owner.into(),
23            repo: repo.into(),
24        }
25    }
26
27    fn path(&self, more: &str) -> String {
28        format!("/repos/{}/{}/check-runs{}", self.owner, self.repo, more)
29    }
30
31    pub fn create(&self, check_run_options: &CheckRunOptions) -> Future<CheckRun> {
32        match serde_json::to_string(check_run_options) {
33            Ok(data) => self.github.post_media::<CheckRun>(
34                &self.path(""),
35                data.into_bytes(),
36                MediaType::Preview("antiope"),
37                AuthenticationConstraint::Unconstrained,
38            ),
39            Err(e) => Box::pin(futures::future::err(e.into())),
40        }
41    }
42
43    pub fn update(
44        &self,
45        check_run_id: &str,
46        check_run_options: &CheckRunUpdateOptions,
47    ) -> Future<CheckRun> {
48        match serde_json::to_string(check_run_options) {
49            Ok(data) => self.github.post_media::<CheckRun>(
50                &self.path(&format!("/{}", check_run_id)),
51                data.into_bytes(),
52                MediaType::Preview("antiope"),
53                AuthenticationConstraint::Unconstrained,
54            ),
55            Err(e) => Box::pin(futures::future::err(e.into())),
56        }
57    }
58
59    pub fn list_for_suite(&self, suite_id: &str) -> Future<Vec<CheckRun>> {
60        // !!! does this actually work?
61        // https://developer.github.com/v3/checks/runs/#list-check-runs-in-a-check-suite
62        self.github.get_media::<Vec<CheckRun>>(
63            &self.path(&format!("/{}/check-runs", suite_id)),
64            MediaType::Preview("antiope"),
65        )
66    }
67}
68
69// representations
70
71#[derive(Debug, Serialize, Deserialize, PartialEq)]
72#[serde(rename_all = "snake_case")]
73pub enum CheckRunState {
74    Queued,
75    InProgress,
76    Completed,
77}
78
79#[derive(Debug, Serialize, Deserialize, PartialEq)]
80#[serde(rename_all = "snake_case")]
81pub enum Conclusion {
82    Success,
83    Failure,
84    Neutral,
85    Cancelled,
86    TimedOut,
87    ActionRequired,
88}
89
90#[derive(Debug, Serialize, Deserialize, PartialEq)]
91#[serde(rename_all = "snake_case")]
92pub enum AnnotationLevel {
93    Notice,
94    Warning,
95    Failure,
96}
97
98#[derive(Debug, Serialize, Deserialize, PartialEq)]
99pub struct Output {
100    pub title: String,
101    pub summary: String,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub text: Option<String>,
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub annotations: Option<Vec<Annotation>>,
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub images: Option<Vec<Image>>,
108}
109
110#[derive(Debug, Serialize, Deserialize, PartialEq)]
111pub struct Action {
112    pub label: String,
113    pub description: String,
114    pub identifier: String,
115}
116
117#[derive(Debug, Serialize, Deserialize, PartialEq)]
118pub struct Annotation {
119    pub path: String,
120    pub start_line: u32,
121    pub end_line: u32,
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub start_column: Option<u32>,
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub end_column: Option<u32>,
126    pub annotation_level: AnnotationLevel,
127    pub message: String,
128    pub title: String,
129    pub raw_details: String,
130}
131
132#[derive(Debug, Serialize, Deserialize, PartialEq)]
133pub struct Image {
134    pub alt: String,
135    pub image_url: String,
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub caption: Option<String>,
138}
139
140#[derive(Debug, Serialize, PartialEq)]
141pub struct CheckRunOptions {
142    pub name: String,
143    pub head_sha: String,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub details_url: Option<String>,
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub external_id: Option<String>,
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub status: Option<CheckRunState>,
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub started_at: Option<String>,
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub conclusion: Option<Conclusion>,
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub completed_at: Option<String>,
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub output: Option<Output>,
158    #[serde(skip_serializing_if = "Option::is_none")]
159    pub actions: Option<Vec<Action>>,
160}
161
162#[derive(Debug, Serialize, PartialEq)]
163pub struct CheckRunUpdateOptions {
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub name: Option<String>,
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub details_url: Option<String>,
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub external_id: Option<String>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub status: Option<CheckRunState>,
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub started_at: Option<String>,
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub conclusion: Option<Conclusion>,
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub completed_at: Option<String>,
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub output: Option<Output>,
180    #[serde(skip_serializing_if = "Option::is_none")]
181    pub actions: Option<Vec<Action>>,
182}
183
184#[derive(Debug, Serialize, Deserialize, PartialEq)]
185pub struct CheckRun {
186    pub id: i32,
187    pub name: String,
188    pub head_sha: String,
189    pub url: String,
190    pub check_suite: CheckSuite,
191    pub details_url: Option<String>,
192    pub external_id: Option<String>,
193    pub status: Option<CheckRunState>,
194    pub started_at: Option<String>,
195    pub conclusion: Option<Conclusion>,
196    pub completed_at: Option<String>,
197    /*
198    Deleted for now:
199
200    GitHub's API returns:
201
202      "output": {
203        "title": null,
204        "summary": null,
205        "text": null,
206        "annotations_count": 0,
207        "annotations_url": "https://api.github.com/repos/grahamc/notpkgs/check-runs/30726963/annotations"
208      },
209
210    if there is no Output, which confuses serde.
211
212
213    pub output: Option<Output>,
214     */
215    pub actions: Option<Vec<Action>>,
216}
217
218#[derive(Debug, Serialize, Deserialize, PartialEq)]
219pub struct CheckSuite {
220    pub id: u32,
221}