use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RepoIdentity {
pub repo_uuid: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
impl RepoIdentity {
pub fn minted(namespace: &str, name: &str) -> Self {
RepoIdentity {
repo_uuid: Uuid::new_v4(),
namespace: Some(namespace.to_string()),
name: Some(name.to_string()),
}
}
pub fn hintless(repo_uuid: Uuid) -> Self {
RepoIdentity {
repo_uuid,
namespace: None,
name: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn server_identity(namespace: &str, name: &str) -> RepoIdentity {
RepoIdentity::minted(namespace, name)
}
#[test]
fn oxen_server_assigns_a_repo_uuid_and_records_both_names() {
let identity = server_identity("ox", "cats");
assert_eq!(identity.namespace.as_deref(), Some("ox"));
assert_eq!(identity.name.as_deref(), Some("cats"));
}
#[test]
fn uuids_serialize_canonically_whatever_form_arrived() {
let identity = RepoIdentity::hintless(
Uuid::parse_str("5abd211ee25c494bba0f44ad542443d7").expect("a valid UUID"),
);
let toml = toml::to_string(&identity).expect("serialize");
assert!(
toml.contains("5abd211e-e25c-494b-ba0f-44ad542443d7"),
"expected canonical hyphenated form in:\n{toml}"
);
}
#[test]
fn absent_name_hints_are_not_serialized() {
let repo_uuid = Uuid::new_v4();
let toml = toml::to_string(&RepoIdentity::hintless(repo_uuid)).expect("serialize");
assert_eq!(toml, format!("repo_uuid = \"{repo_uuid}\"\n"));
}
#[test]
fn an_identity_without_a_repo_uuid_is_rejected() {
assert!(toml::from_str::<RepoIdentity>("namespace = \"ox\"\n").is_err());
}
}