#[derive(Debug, Clone, serde::Serialize)]
pub struct HealthTrend {
pub compared_to: TrendPoint,
pub metrics: Vec<TrendMetric>,
pub snapshots_loaded: usize,
pub overall_direction: TrendDirection,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TrendPoint {
pub timestamp: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub git_sha: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub grade: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub coverage_model: Option<super::CoverageModel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snapshot_schema_version: Option<u32>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TrendMetric {
pub name: &'static str,
pub label: &'static str,
pub previous: f64,
pub current: f64,
pub delta: f64,
pub direction: TrendDirection,
pub unit: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_count: Option<TrendCount>,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_count: Option<TrendCount>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct TrendCount {
pub value: usize,
pub total: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TrendDirection {
Improving,
Declining,
Stable,
}
impl TrendDirection {
#[must_use]
pub const fn arrow(self) -> &'static str {
match self {
Self::Improving => "\u{2191}", Self::Declining => "\u{2193}", Self::Stable => "\u{2192}", }
}
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Improving => "improving",
Self::Declining => "declining",
Self::Stable => "stable",
}
}
}