1use crate::models::RunId;
2use crate::{models, Octocrab, Page, Result};
3
4pub struct WorkflowsHandler<'octo> {
5 crab: &'octo Octocrab,
6 owner: String,
7 repo: String,
8}
9
10impl<'octo> WorkflowsHandler<'octo> {
14 pub(crate) fn new(crab: &'octo Octocrab, owner: String, repo: String) -> Self {
15 Self { crab, owner, repo }
16 }
17
18 pub fn list(&self) -> ListWorkflowsBuilder<'_, '_> {
35 ListWorkflowsBuilder::new(self)
36 }
37
38 pub async fn get(&self, run_id: RunId) -> Result<models::workflows::Run> {
39 let route = format!(
40 "/repos/{owner}/{repo}/actions/runs/{run_id}",
41 owner = self.owner,
42 repo = self.repo,
43 run_id = run_id,
44 );
45
46 self.crab.get(route, None::<&()>).await
47 }
48
49 pub fn list_runs(&self, workflow_file_or_id: impl Into<String>) -> ListRunsBuilder<'_, '_> {
71 ListRunsBuilder::new(
72 self,
73 ListRunsRequestType::ByWorkflow(workflow_file_or_id.into()),
74 )
75 }
76
77 pub fn list_all_runs(&self) -> ListRunsBuilder<'_, '_> {
98 ListRunsBuilder::new(self, ListRunsRequestType::ByRepo)
99 }
100
101 pub fn list_jobs(&self, run_id: RunId) -> ListJobsBuilder<'_, '_> {
120 ListJobsBuilder::new(self, run_id)
121 }
122}
123
124#[derive(serde::Serialize)]
125pub struct ListWorkflowsBuilder<'octo, 'b> {
126 #[serde(skip)]
127 handler: &'b WorkflowsHandler<'octo>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 per_page: Option<u8>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 page: Option<u32>,
132}
133
134impl<'octo, 'b> ListWorkflowsBuilder<'octo, 'b> {
135 pub(crate) fn new(handler: &'b WorkflowsHandler<'octo>) -> Self {
136 Self {
137 handler,
138 per_page: None,
139 page: None,
140 }
141 }
142
143 pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
145 self.per_page = Some(per_page.into());
146 self
147 }
148
149 pub fn page(mut self, page: impl Into<u32>) -> Self {
151 self.page = Some(page.into());
152 self
153 }
154
155 pub async fn send(self) -> Result<Page<models::workflows::WorkFlow>> {
157 let route = format!(
158 "/repos/{owner}/{repo}/actions/workflows",
159 owner = self.handler.owner,
160 repo = self.handler.repo
161 );
162 self.handler.crab.get(route, Some(&self)).await
163 }
164}
165
166pub(crate) enum ListRunsRequestType {
168 ByRepo,
169 ByWorkflow(String),
170}
171
172#[derive(serde::Serialize)]
173pub struct ListRunsBuilder<'octo, 'b> {
174 #[serde(skip)]
175 handler: &'b WorkflowsHandler<'octo>,
176 #[serde(skip)]
177 r#type: ListRunsRequestType,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 actor: Option<String>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 branch: Option<String>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 event: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 status: Option<String>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 per_page: Option<u8>,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 page: Option<u32>,
190 #[serde(skip_serializing_if = "Option::is_none")]
191 exclude_pull_requests: Option<bool>,
192}
193
194impl<'octo, 'b> ListRunsBuilder<'octo, 'b> {
195 pub(crate) fn new(handler: &'b WorkflowsHandler<'octo>, r#type: ListRunsRequestType) -> Self {
196 Self {
197 handler,
198 r#type,
199 actor: None,
200 branch: None,
201 event: None,
202 status: None,
203 per_page: None,
204 page: None,
205 exclude_pull_requests: None,
206 }
207 }
208
209 pub fn actor(mut self, actor: impl Into<String>) -> Self {
211 self.actor = Some(actor.into());
212 self
213 }
214
215 pub fn branch(mut self, branch: impl Into<String>) -> Self {
217 self.branch = Some(branch.into());
218 self
219 }
220
221 pub fn event(mut self, event: impl Into<String>) -> Self {
224 self.event = Some(event.into());
225 self
226 }
227
228 pub fn status(mut self, status: impl Into<String>) -> Self {
231 self.status = Some(status.into());
232 self
233 }
234
235 pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
237 self.per_page = Some(per_page.into());
238 self
239 }
240
241 pub fn page(mut self, page: impl Into<u32>) -> Self {
243 self.page = Some(page.into());
244 self
245 }
246
247 pub fn exclude_pull_requests(mut self, exclude_pull_requests: impl Into<bool>) -> Self {
249 self.exclude_pull_requests = Some(exclude_pull_requests.into());
250 self
251 }
252
253 pub async fn send(self) -> Result<Page<models::workflows::Run>> {
255 let route = match self.r#type {
256 ListRunsRequestType::ByRepo => format!(
257 "/repos/{owner}/{repo}/actions/runs",
258 owner = self.handler.owner,
259 repo = self.handler.repo
260 ),
261 ListRunsRequestType::ByWorkflow(ref workflow_id) => format!(
262 "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs",
263 owner = self.handler.owner,
264 repo = self.handler.repo,
265 workflow_id = workflow_id
266 ),
267 };
268 self.handler.crab.get(route, Some(&self)).await
269 }
270}
271
272#[derive(serde::Serialize)]
273pub struct ListJobsBuilder<'octo, 'b> {
274 #[serde(skip)]
275 handler: &'b WorkflowsHandler<'octo>,
276 #[serde(skip)]
277 run_id: RunId,
278 #[serde(skip_serializing_if = "Option::is_none")]
279 filter: Option<crate::params::workflows::Filter>,
280 #[serde(skip_serializing_if = "Option::is_none")]
281 per_page: Option<u8>,
282 #[serde(skip_serializing_if = "Option::is_none")]
283 page: Option<u32>,
284}
285
286impl<'octo, 'b> ListJobsBuilder<'octo, 'b> {
287 pub(crate) fn new(handler: &'b WorkflowsHandler<'octo>, run_id: RunId) -> Self {
288 Self {
289 handler,
290 run_id,
291 per_page: None,
292 page: None,
293 filter: None,
294 }
295 }
296
297 pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
299 self.per_page = Some(per_page.into());
300 self
301 }
302
303 pub fn page(mut self, page: impl Into<u32>) -> Self {
305 self.page = Some(page.into());
306 self
307 }
308
309 pub fn filter(mut self, filter: impl Into<crate::params::workflows::Filter>) -> Self {
311 self.filter = Some(filter.into());
312 self
313 }
314
315 pub async fn send(self) -> Result<Page<models::workflows::Job>> {
317 let route = format!(
318 "/repos/{owner}/{repo}/actions/runs/{run_id}/jobs",
319 owner = self.handler.owner,
320 repo = self.handler.repo,
321 run_id = self.run_id,
322 );
323 self.handler.crab.get(route, Some(&self)).await
324 }
325}
326
327#[cfg(test)]
328mod tests {
329 #[tokio::test]
330 async fn serialize() {
331 use crate::params::workflows::Filter;
332
333 let octocrab = crate::Octocrab::default();
334 let handler = octocrab.workflows("rust-lang", "rust");
335 let list_jobs = handler
336 .list_jobs(1234u64.into())
337 .filter(Filter::All)
338 .per_page(100)
339 .page(1u8);
340
341 assert_eq!(
342 serde_json::to_value(list_jobs).unwrap(),
343 serde_json::json!({
344 "filter": "all",
345 "per_page": 100,
346 "page": 1,
347 })
348 )
349 }
350}