use crate::TemporalAxis;
use super::shared_label::SharedLabel;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CoordinateRelationKind {
SharesScope,
Before,
After,
During,
Concurrent,
SameSequence,
SameRank,
}
impl CoordinateRelationKind {
pub fn name(self) -> &'static str {
match self {
Self::SharesScope => "shares_scope",
Self::Before => "before",
Self::After => "after",
Self::During => "during",
Self::Concurrent => "concurrent",
Self::SameSequence => "same_sequence",
Self::SameRank => "same_rank",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CoordinateRelation {
from: String,
to: String,
kind: CoordinateRelationKind,
dimension: String,
scope_id: String,
axis: TemporalAxis,
}
impl CoordinateRelation {
pub fn new(
from: impl Into<String>,
to: impl Into<String>,
kind: CoordinateRelationKind,
label: &SharedLabel,
axis: TemporalAxis,
) -> Self {
Self {
from: from.into(),
to: to.into(),
kind,
dimension: label.key().to_string(),
scope_id: label.value().to_string(),
axis,
}
}
pub fn from(&self) -> &str {
&self.from
}
pub fn to(&self) -> &str {
&self.to
}
pub fn kind(&self) -> CoordinateRelationKind {
self.kind
}
pub fn dimension(&self) -> &str {
&self.dimension
}
pub fn scope_id(&self) -> &str {
&self.scope_id
}
pub fn axis(&self) -> TemporalAxis {
self.axis
}
pub fn why(&self) -> String {
let scope = format!("{}={}", self.dimension, self.scope_id);
let clock = clock_name(self.axis);
match self.kind {
CoordinateRelationKind::SharesScope => format!(
"Both stand in `{scope}`; neither carries an instant on the {clock} clock to order them by."
),
CoordinateRelationKind::Before => format!(
"Both stand in `{scope}`; `{}` comes before `{}` on the {clock} clock.",
self.from, self.to
),
CoordinateRelationKind::After => format!(
"Both stand in `{scope}`; `{}` comes after `{}` on the {clock} clock.",
self.from, self.to
),
CoordinateRelationKind::During => format!(
"Both stand in `{scope}`; `{}` holds within the span of `{}` on the validity clock.",
self.from, self.to
),
CoordinateRelationKind::Concurrent => format!(
"Both stand in `{scope}`; `{}` and `{}` hold at once on the {clock} clock.",
self.from, self.to
),
CoordinateRelationKind::SameSequence => {
format!("Both stand in `{scope}` at the same sequence.")
}
CoordinateRelationKind::SameRank => {
format!("Both stand in `{scope}` at the same rank.")
}
}
}
}
fn clock_name(axis: TemporalAxis) -> &'static str {
match axis {
TemporalAxis::Default => "default",
TemporalAxis::Occurred => "occurred",
TemporalAxis::Observed => "observed",
TemporalAxis::Ingested => "ingested",
TemporalAxis::Validity => "validity",
}
}