#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Totality {
Total,
Partial,
Corecursive(&'static str),
Unknown,
}
impl Totality {
#[must_use]
pub const fn is_total(&self) -> bool {
matches!(self, Self::Total)
}
#[must_use]
pub const fn is_gold_eligible(&self) -> bool {
matches!(self, Self::Total | Self::Corecursive(_))
}
#[must_use]
pub const fn label(&self) -> &'static str {
match self {
Self::Total => "@total",
Self::Partial => "@partial",
Self::Corecursive(_) => "@corecursive",
Self::Unknown => "(unmarked)",
}
}
#[must_use]
pub fn from_decorator(name: &str) -> Option<Self> {
match name {
"total" => Some(Self::Total),
"partial" => Some(Self::Partial),
_ => None,
}
}
}
impl Default for Totality {
fn default() -> Self {
Self::Unknown
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_totality_is_total() {
assert!(Totality::Total.is_total());
assert!(!Totality::Partial.is_total());
assert!(!Totality::Corecursive("server loop").is_total());
assert!(!Totality::Unknown.is_total());
}
#[test]
fn test_gold_eligibility() {
assert!(Totality::Total.is_gold_eligible());
assert!(Totality::Corecursive("event loop").is_gold_eligible());
assert!(!Totality::Partial.is_gold_eligible());
assert!(!Totality::Unknown.is_gold_eligible());
}
#[test]
fn test_label() {
assert_eq!(Totality::Total.label(), "@total");
assert_eq!(Totality::Partial.label(), "@partial");
assert_eq!(Totality::Corecursive("x").label(), "@corecursive");
assert_eq!(Totality::Unknown.label(), "(unmarked)");
}
#[test]
fn test_from_decorator() {
assert_eq!(Totality::from_decorator("total"), Some(Totality::Total));
assert_eq!(Totality::from_decorator("partial"), Some(Totality::Partial));
assert_eq!(Totality::from_decorator("verified"), None);
assert_eq!(Totality::from_decorator("gold"), None);
}
#[test]
fn test_default_is_unknown() {
assert_eq!(Totality::default(), Totality::Unknown);
}
}