use std::time::SystemTime;
use serde::{Deserialize, Serialize};
use super::status::HealthStatus;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct LivenessReport {
status: HealthStatus,
observed_at: SystemTime,
}
impl LivenessReport {
#[must_use]
pub fn new(status: HealthStatus) -> Self {
Self {
status,
observed_at: SystemTime::now(),
}
}
#[must_use]
pub const fn at(status: HealthStatus, observed_at: SystemTime) -> Self {
Self {
status,
observed_at,
}
}
#[must_use]
pub fn healthy() -> Self {
Self::new(HealthStatus::Healthy)
}
#[must_use]
pub fn degraded() -> Self {
Self::new(HealthStatus::Degraded)
}
#[must_use]
pub fn unhealthy() -> Self {
Self::new(HealthStatus::Unhealthy)
}
#[must_use]
pub fn unknown() -> Self {
Self::new(HealthStatus::Unknown)
}
#[must_use]
pub const fn status(&self) -> HealthStatus {
self.status
}
#[must_use]
pub const fn observed_at(&self) -> SystemTime {
self.observed_at
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::{Duration, UNIX_EPOCH};
#[test]
fn explicit_timestamp_is_preserved() {
let observed_at = UNIX_EPOCH + Duration::from_secs(42);
let report = LivenessReport::at(HealthStatus::Healthy, observed_at);
assert_eq!(report.status(), HealthStatus::Healthy);
assert_eq!(report.observed_at(), observed_at);
}
#[test]
fn convenience_constructors_use_expected_statuses() {
assert_eq!(LivenessReport::healthy().status(), HealthStatus::Healthy);
assert_eq!(LivenessReport::degraded().status(), HealthStatus::Degraded);
assert_eq!(
LivenessReport::unhealthy().status(),
HealthStatus::Unhealthy
);
assert_eq!(LivenessReport::unknown().status(), HealthStatus::Unknown);
}
#[test]
fn new_records_a_current_observation_time() {
let before = SystemTime::now();
let report = LivenessReport::new(HealthStatus::Healthy);
let after = SystemTime::now();
assert!(report.observed_at() >= before);
assert!(report.observed_at() <= after);
}
#[test]
fn liveness_contains_no_readiness_state() {
let report = LivenessReport::healthy();
assert_eq!(report.status(), HealthStatus::Healthy);
}
#[test]
fn reports_with_identical_data_are_equal() {
let observed_at = UNIX_EPOCH + Duration::from_secs(100);
let first = LivenessReport::at(HealthStatus::Degraded, observed_at);
let second = LivenessReport::at(HealthStatus::Degraded, observed_at);
assert_eq!(first, second);
}
}