use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PipelineBasic {
pub id: u64,
#[serde(rename = "ref")]
pub ref_name: String,
pub status: PipelineStatus,
pub source: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub web_url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Pipeline {
pub id: u64,
pub iid: Option<u64>,
#[serde(rename = "ref")]
pub ref_name: String,
pub status: PipelineStatus,
pub source: Option<String>,
pub sha: String,
#[serde(default)]
pub short_sha: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub duration: Option<f64>,
pub queued_duration: Option<f64>,
pub web_url: String,
pub coverage: Option<String>,
#[serde(default)]
pub user: Option<PipelineUser>,
#[serde(default)]
pub triggered: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PipelineUser {
pub id: u64,
pub username: String,
pub name: String,
pub state: String,
pub avatar_url: Option<String>,
pub web_url: String,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum PipelineStatus {
Created,
Pending,
Preparing,
Running,
Success,
Failed,
Canceled,
Skipped,
Manual,
Scheduled,
}
impl PipelineStatus {
pub fn is_finished(self) -> bool {
matches!(
self,
Self::Success | Self::Failed | Self::Canceled | Self::Skipped
)
}
pub fn is_active(self) -> bool {
matches!(
self,
Self::Created | Self::Pending | Self::Preparing | Self::Running
)
}
pub fn is_successful(self) -> bool {
self == Self::Success
}
pub fn is_failed(self) -> bool {
self == Self::Failed
}
}
impl std::fmt::Display for PipelineStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Created => write!(f, "created"),
Self::Pending => write!(f, "pending"),
Self::Preparing => write!(f, "preparing"),
Self::Running => write!(f, "running"),
Self::Success => write!(f, "success"),
Self::Failed => write!(f, "failed"),
Self::Canceled => write!(f, "canceled"),
Self::Skipped => write!(f, "skipped"),
Self::Manual => write!(f, "manual"),
Self::Scheduled => write!(f, "scheduled"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pipeline_status_is_finished() {
assert!(PipelineStatus::Success.is_finished());
assert!(PipelineStatus::Failed.is_finished());
assert!(PipelineStatus::Canceled.is_finished());
assert!(PipelineStatus::Skipped.is_finished());
assert!(!PipelineStatus::Running.is_finished());
assert!(!PipelineStatus::Pending.is_finished());
}
#[test]
fn test_pipeline_status_is_active() {
assert!(PipelineStatus::Running.is_active());
assert!(PipelineStatus::Pending.is_active());
assert!(PipelineStatus::Created.is_active());
assert!(PipelineStatus::Preparing.is_active());
assert!(!PipelineStatus::Success.is_active());
assert!(!PipelineStatus::Failed.is_active());
}
#[test]
fn test_pipeline_status_display() {
assert_eq!(PipelineStatus::Success.to_string(), "success");
assert_eq!(PipelineStatus::Failed.to_string(), "failed");
assert_eq!(PipelineStatus::Running.to_string(), "running");
}
#[test]
fn test_pipeline_status_serialization() {
let status = PipelineStatus::Success;
let json = serde_json::to_string(&status).unwrap();
assert_eq!(json, "\"success\"");
let deserialized: PipelineStatus = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, PipelineStatus::Success);
}
}