use serde::{Deserialize, Serialize};
use crate::column::CanonicalColumnName;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(tag = "kind", content = "name", rename_all = "snake_case")]
pub enum EtlUnitRef {
Measurement(CanonicalColumnName),
Quality(CanonicalColumnName),
Derivation(CanonicalColumnName),
}
impl EtlUnitRef {
pub fn measurement(name: impl Into<CanonicalColumnName>) -> Self {
Self::Measurement(name.into())
}
pub fn quality(name: impl Into<CanonicalColumnName>) -> Self {
Self::Quality(name.into())
}
pub fn derivation(name: impl Into<CanonicalColumnName>) -> Self {
Self::Derivation(name.into())
}
pub fn name(&self) -> &CanonicalColumnName {
match self {
Self::Measurement(n) | Self::Quality(n) | Self::Derivation(n) => n,
}
}
pub fn as_str(&self) -> &str {
self.name().as_str()
}
pub fn is_measurement(&self) -> bool {
matches!(self, Self::Measurement(_))
}
pub fn is_quality(&self) -> bool {
matches!(self, Self::Quality(_))
}
pub fn is_derivation(&self) -> bool {
matches!(self, Self::Derivation(_))
}
}
impl std::fmt::Display for EtlUnitRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Measurement(n) => write!(f, "Measurement({})", n.as_str()),
Self::Quality(n) => write!(f, "Quality({})", n.as_str()),
Self::Derivation(n) => write!(f, "Derivation({})", n.as_str()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_measurement_ref() {
let r = EtlUnitRef::measurement("sump");
assert!(r.is_measurement());
assert!(!r.is_quality());
assert!(!r.is_derivation());
assert_eq!(r.as_str(), "sump");
assert_eq!(format!("{}", r), "Measurement(sump)");
}
#[test]
fn test_quality_ref() {
let r = EtlUnitRef::quality("parish");
assert!(r.is_quality());
assert_eq!(r.as_str(), "parish");
}
#[test]
fn test_derivation_ref() {
let r = EtlUnitRef::derivation("total_runtime");
assert!(r.is_derivation());
assert_eq!(r.as_str(), "total_runtime");
}
#[test]
fn test_equality() {
let a = EtlUnitRef::measurement("sump");
let b = EtlUnitRef::measurement("sump");
let c = EtlUnitRef::quality("sump");
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
fn test_serde_roundtrip() {
let refs = vec![
EtlUnitRef::measurement("sump"),
EtlUnitRef::quality("parish"),
EtlUnitRef::derivation("engine_any"),
];
let json = serde_json::to_string(&refs).unwrap();
let deserialized: Vec<EtlUnitRef> = serde_json::from_str(&json).unwrap();
assert_eq!(refs, deserialized);
}
}