use crate::error::{GitLabError, Result};
use crate::models::{Pipeline, PipelineBasic, PipelineStatus};
use gitlab::Gitlab;
use gitlab::api::{Query, projects::pipelines};
pub struct PipelineListBuilder<'a> {
client: &'a Gitlab,
project: String,
status: Option<PipelineStatus>,
ref_name: Option<String>,
limit: Option<usize>,
}
impl<'a> PipelineListBuilder<'a> {
pub(crate) fn new(client: &'a Gitlab, project: impl Into<String>) -> Self {
Self {
client,
project: project.into(),
status: None,
ref_name: None,
limit: None,
}
}
pub fn status(mut self, status: PipelineStatus) -> Self {
self.status = Some(status);
self
}
pub fn ref_name(mut self, ref_name: impl Into<String>) -> Self {
self.ref_name = Some(ref_name.into());
self
}
pub fn limit(mut self, limit: usize) -> Self {
self.limit = Some(limit);
self
}
pub async fn list(self) -> Result<Vec<PipelineBasic>> {
let endpoint = pipelines::Pipelines::builder()
.project(&self.project)
.build()
.map_err(|e| GitLabError::api(format!("Failed to build pipeline endpoint: {}", e)))?;
let mut pipelines: Vec<PipelineBasic> = endpoint
.query(self.client)
.map_err(|e| GitLabError::api(format!("Failed to query pipelines: {}", e)))?;
if let Some(status) = self.status {
pipelines.retain(|p| p.status == status);
}
if let Some(ref_name) = self.ref_name {
pipelines.retain(|p| p.ref_name == ref_name);
}
if let Some(limit) = self.limit {
pipelines.truncate(limit);
}
Ok(pipelines)
}
}
pub struct PipelineBuilder<'a> {
client: &'a Gitlab,
project: String,
pipeline_id: u64,
}
impl<'a> PipelineBuilder<'a> {
pub(crate) fn new(client: &'a Gitlab, project: impl Into<String>, pipeline_id: u64) -> Self {
Self {
client,
project: project.into(),
pipeline_id,
}
}
pub async fn get(self) -> Result<Pipeline> {
let endpoint = pipelines::Pipeline::builder()
.project(&self.project)
.pipeline(self.pipeline_id)
.build()
.map_err(|e| GitLabError::api(format!("Failed to build pipeline endpoint: {}", e)))?;
endpoint.query(self.client).map_err(|e| match e {
gitlab::api::ApiError::GitlabService { status, .. } if status.as_u16() == 404 => {
GitLabError::not_found("pipeline", self.pipeline_id)
}
_ => GitLabError::api(format!("Failed to get pipeline: {}", e)),
})
}
pub async fn retry(self) -> Result<Pipeline> {
let endpoint = pipelines::RetryPipeline::builder()
.project(&self.project)
.pipeline(self.pipeline_id)
.build()
.map_err(|e| GitLabError::api(format!("Failed to build retry endpoint: {}", e)))?;
endpoint
.query(self.client)
.map_err(|e| GitLabError::api(format!("Failed to retry pipeline: {}", e)))
}
pub async fn cancel(self) -> Result<Pipeline> {
let endpoint = pipelines::CancelPipeline::builder()
.project(&self.project)
.pipeline(self.pipeline_id)
.build()
.map_err(|e| GitLabError::api(format!("Failed to build cancel endpoint: {}", e)))?;
endpoint
.query(self.client)
.map_err(|e| GitLabError::api(format!("Failed to cancel pipeline: {}", e)))
}
}
pub struct PipelineApi;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pipeline_list_builder() {
fn _compile_test(client: &Gitlab) {
let _builder = PipelineListBuilder::new(client, "project")
.status(PipelineStatus::Failed)
.ref_name("main")
.limit(10);
}
}
#[test]
fn test_pipeline_builder() {
fn _compile_test(client: &Gitlab) {
let _builder = PipelineBuilder::new(client, "project", 123);
}
}
}