use serde::{Deserialize, Serialize};
use super::{Forge, Visibility};
pub(crate) fn is_false(b: &bool) -> bool {
!*b
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Repo {
pub name: String,
pub description: Option<String>,
pub visibility: Visibility,
pub origin: Forge,
#[serde(default)]
pub mirrors: Vec<Forge>,
#[serde(default)]
pub protected: bool,
#[serde(default, skip_serializing_if = "is_false")]
pub staged_for_deletion: bool,
}
impl Repo {
pub fn new(name: impl Into<String>, origin: Forge) -> Self {
Self {
name: name.into(),
description: None,
visibility: Visibility::Public,
origin,
mirrors: Vec::new(),
protected: false,
staged_for_deletion: false,
}
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
pub fn with_visibility(mut self, visibility: Visibility) -> Self {
self.visibility = visibility;
self
}
pub fn with_mirror(mut self, forge: Forge) -> Self {
if !self.mirrors.contains(&forge) && forge != self.origin {
self.mirrors.push(forge);
}
self
}
pub fn with_mirrors(mut self, mirrors: Vec<Forge>) -> Self {
self.mirrors = mirrors.into_iter()
.filter(|f| *f != self.origin)
.collect();
self
}
pub fn with_protected(mut self, protected: bool) -> Self {
self.protected = protected;
self
}
pub fn with_staged_for_deletion(mut self, staged: bool) -> Self {
self.staged_for_deletion = staged;
self
}
pub fn all_forges(&self) -> Vec<Forge> {
let mut forges = vec![self.origin.clone()];
forges.extend(self.mirrors.clone());
forges
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_repo_new() {
let repo = Repo::new("test-repo", Forge::GitHub);
assert_eq!(repo.name, "test-repo");
assert_eq!(repo.origin, Forge::GitHub);
assert!(repo.mirrors.is_empty());
assert!(!repo.protected);
}
#[test]
fn test_repo_builder() {
let repo = Repo::new("my-app", Forge::GitHub)
.with_description("My application")
.with_visibility(Visibility::Private)
.with_mirror(Forge::Codeberg)
.with_protected(true);
assert_eq!(repo.name, "my-app");
assert_eq!(repo.description, Some("My application".to_string()));
assert_eq!(repo.visibility, Visibility::Private);
assert_eq!(repo.origin, Forge::GitHub);
assert_eq!(repo.mirrors, vec![Forge::Codeberg]);
assert!(repo.protected);
}
#[test]
fn test_repo_mirrors_excludes_origin() {
let repo = Repo::new("test", Forge::GitHub)
.with_mirrors(vec![Forge::GitHub, Forge::Codeberg, Forge::GitLab]);
assert_eq!(repo.mirrors.len(), 2);
assert!(repo.mirrors.contains(&Forge::Codeberg));
assert!(repo.mirrors.contains(&Forge::GitLab));
assert!(!repo.mirrors.contains(&Forge::GitHub));
}
#[test]
fn test_repo_all_forges() {
let repo = Repo::new("test", Forge::GitHub)
.with_mirror(Forge::Codeberg);
let all = repo.all_forges();
assert_eq!(all.len(), 2);
assert_eq!(all[0], Forge::GitHub); assert_eq!(all[1], Forge::Codeberg);
}
}