use crate::payload::Violation;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Timestamp(pub i64);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Duration(pub i64);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Envelope {
pub stamp: Timestamp,
pub seq: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Provenance {
Init,
Live,
Invalid(Cause),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Cause {
Declared,
Detected(Detection),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Detection {
InvalidValue(Violation),
Corrupt,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Freshness {
Fresh,
Stale {
by: Duration,
},
Unbounded,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Sample<T> {
pub value: T,
pub provenance: Provenance,
pub freshness: Freshness,
pub envelope: Envelope,
}
impl<T> Sample<T> {
pub fn usable(&self) -> bool {
matches!(self.provenance, Provenance::Live)
&& !matches!(self.freshness, Freshness::Stale { .. })
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Occurrence<T> {
pub payload: Result<T, Detection>,
pub envelope: Envelope,
}
#[cfg(test)]
mod tests {
use super::{Cause, Detection, Duration, Envelope, Freshness, Provenance, Sample, Timestamp};
use crate::payload::{Rule, Violation};
fn sample(provenance: Provenance, freshness: Freshness) -> Sample<u8> {
Sample {
value: 0,
provenance,
freshness,
envelope: Envelope {
stamp: Timestamp(0),
seq: 0,
},
}
}
#[test]
fn only_a_live_value_that_is_not_stale_is_usable() {
let violation = Violation {
type_name: "Speed",
rule: Rule::Range,
};
let provenances = [
Provenance::Init,
Provenance::Live,
Provenance::Invalid(Cause::Declared),
Provenance::Invalid(Cause::Detected(Detection::InvalidValue(violation))),
Provenance::Invalid(Cause::Detected(Detection::Corrupt)),
];
let freshnesses = [
Freshness::Fresh,
Freshness::Stale { by: Duration(1) },
Freshness::Unbounded,
];
for provenance in provenances {
for freshness in freshnesses {
let expected =
provenance == Provenance::Live && !matches!(freshness, Freshness::Stale { .. });
assert_eq!(
sample(provenance, freshness).usable(),
expected,
"{provenance:?} with {freshness:?}"
);
}
}
}
}