use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SchemaComponent {
DoctorReliability,
Status,
RepoUpdaterContract,
ProcessTriageContract,
}
#[must_use]
pub const fn current_version(component: SchemaComponent) -> &'static str {
match component {
SchemaComponent::DoctorReliability => "1.0.0",
SchemaComponent::Status => "1.0.0",
SchemaComponent::RepoUpdaterContract => "1.0.0",
SchemaComponent::ProcessTriageContract => "1.0.0",
}
}
pub const ALL_COMPONENTS: &[(SchemaComponent, &str)] = &[
(
SchemaComponent::DoctorReliability,
current_version(SchemaComponent::DoctorReliability),
),
(
SchemaComponent::Status,
current_version(SchemaComponent::Status),
),
(
SchemaComponent::RepoUpdaterContract,
current_version(SchemaComponent::RepoUpdaterContract),
),
(
SchemaComponent::ProcessTriageContract,
current_version(SchemaComponent::ProcessTriageContract),
),
];
#[cfg(test)]
mod tests {
use super::*;
const PINNED_SNAPSHOT: &[(SchemaComponent, &str)] = &[
(SchemaComponent::DoctorReliability, "1.0.0"),
(SchemaComponent::Status, "1.0.0"),
(SchemaComponent::RepoUpdaterContract, "1.0.0"),
(SchemaComponent::ProcessTriageContract, "1.0.0"),
];
#[test]
fn test_schema_versions_match_snapshot() {
assert_eq!(
ALL_COMPONENTS.len(),
PINNED_SNAPSHOT.len(),
"Number of components changed without snapshot update. \
Either add the missing entry to PINNED_SNAPSHOT or remove the unused entry from ALL_COMPONENTS."
);
for (i, ((c1, v1), (c2, v2))) in ALL_COMPONENTS
.iter()
.zip(PINNED_SNAPSHOT.iter())
.enumerate()
{
assert_eq!(
(c1, *v1),
(c2, *v2),
"Mismatch at position {i}: ALL_COMPONENTS has ({c1:?}, {v1}); \
PINNED_SNAPSHOT has ({c2:?}, {v2}). \
Bump procedure: edit current_version() AND PINNED_SNAPSHOT in the same commit."
);
}
}
#[test]
fn test_current_version_is_const_eval_friendly() {
const _DR: &str = current_version(SchemaComponent::DoctorReliability);
const _ST: &str = current_version(SchemaComponent::Status);
const _RU: &str = current_version(SchemaComponent::RepoUpdaterContract);
const _PT: &str = current_version(SchemaComponent::ProcessTriageContract);
}
#[test]
fn test_versions_match_semver_shape() {
for &(_, version) in ALL_COMPONENTS {
let parts: Vec<&str> = version.split('.').collect();
assert_eq!(
parts.len(),
3,
"version {version} must be MAJOR.MINOR.PATCH (got {} parts)",
parts.len()
);
for p in parts {
assert!(
p.chars().all(|ch| ch.is_ascii_digit()),
"version {version} contains non-numeric component {p}"
);
}
}
}
#[test]
fn test_all_components_unique() {
use std::collections::HashSet;
let set: HashSet<_> = ALL_COMPONENTS.iter().map(|(c, _)| *c).collect();
assert_eq!(
set.len(),
ALL_COMPONENTS.len(),
"duplicate SchemaComponent in ALL_COMPONENTS"
);
}
}