use serde::{Deserialize, Serialize};
use crate::{CursorPage, GitLabVisibility, OwnerRef};
pub type RuntimeRepositoryRecordPage = CursorPage<RuntimeRepositoryRecord>;
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum RuntimeRepositoryStatus {
Importing,
#[default]
Ready,
Failed,
}
impl RuntimeRepositoryStatus {
pub fn as_str(self) -> &'static str {
match self {
Self::Importing => "importing",
Self::Ready => "ready",
Self::Failed => "failed",
}
}
pub fn parse(value: &str) -> Self {
match value.trim() {
"importing" => Self::Importing,
"failed" => Self::Failed,
_ => Self::Ready,
}
}
pub fn from_gitlab_import(import_status: Option<&str>, default_branch: Option<&str>) -> Self {
match import_status.map(str::trim).unwrap_or_default() {
"failed" => Self::Failed,
"scheduled" | "started" => Self::Importing,
"finished" => Self::Ready,
"none" | "" if default_branch.is_some() => Self::Ready,
_ => Self::Importing,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct RuntimeRepositoryRecord {
pub id: String,
pub tenant_id: String,
pub project_id: String,
pub template_id: String,
pub owners: Vec<OwnerRef>,
pub namespace: String,
pub gitlab_project_id: u64,
pub path_with_namespace: String,
pub repository_url: String,
pub default_branch: Option<String>,
#[serde(default)]
pub status: RuntimeRepositoryStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error_message: Option<String>,
pub version: i64,
pub created_at: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct CreateRuntimeRepositoryRequest {
pub template_id: String,
pub project_name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub project_path: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default)]
pub visibility: GitLabVisibility,
#[serde(default)]
pub owners: Vec<OwnerRef>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn gitlab_import_status_maps_to_repository_status() {
assert_eq!(
RuntimeRepositoryStatus::from_gitlab_import(Some("started"), None),
RuntimeRepositoryStatus::Importing
);
assert_eq!(
RuntimeRepositoryStatus::from_gitlab_import(Some("finished"), Some("master")),
RuntimeRepositoryStatus::Ready
);
assert_eq!(
RuntimeRepositoryStatus::from_gitlab_import(Some("none"), Some("master")),
RuntimeRepositoryStatus::Ready
);
assert_eq!(
RuntimeRepositoryStatus::from_gitlab_import(Some("none"), None),
RuntimeRepositoryStatus::Importing
);
assert_eq!(
RuntimeRepositoryStatus::from_gitlab_import(Some("failed"), None),
RuntimeRepositoryStatus::Failed
);
}
#[test]
fn record_defaults_missing_status_to_ready() {
let record: RuntimeRepositoryRecord = serde_json::from_value(serde_json::json!({
"id": "rrepo-1",
"tenantId": "local",
"projectId": "default",
"templateId": "rtpl-1",
"owners": [],
"namespace": "runtimes",
"gitlabProjectId": 1,
"pathWithNamespace": "runtimes/demo",
"repositoryUrl": "https://git.test/runtimes/demo.git",
"defaultBranch": "master",
"version": 1,
"createdAt": "t",
"updatedAt": "t"
}))
.unwrap();
assert_eq!(record.status, RuntimeRepositoryStatus::Ready);
assert_eq!(record.error_message, None);
}
}