fallow_cli/health_types/
trends.rs1#[derive(Debug, Clone, serde::Serialize)]
6#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
7pub struct HealthTrend {
8 pub compared_to: TrendPoint,
10 pub metrics: Vec<TrendMetric>,
12 pub snapshots_loaded: usize,
14 pub overall_direction: TrendDirection,
16}
17
18#[derive(Debug, Clone, serde::Serialize)]
20#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
21pub struct TrendPoint {
22 pub timestamp: String,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub git_sha: Option<String>,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
29 pub score: Option<f64>,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
32 pub grade: Option<String>,
33 #[serde(default, skip_serializing_if = "Option::is_none")]
35 pub coverage_model: Option<super::CoverageModel>,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub snapshot_schema_version: Option<u32>,
39}
40
41#[derive(Debug, Clone, serde::Serialize)]
43#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
44pub struct TrendMetric {
45 pub name: &'static str,
47 pub label: &'static str,
49 pub previous: f64,
51 pub current: f64,
53 pub delta: f64,
55 pub direction: TrendDirection,
57 pub unit: &'static str,
59 #[serde(default, skip_serializing_if = "Option::is_none")]
61 pub previous_count: Option<TrendCount>,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub current_count: Option<TrendCount>,
65}
66
67#[derive(Debug, Clone, serde::Serialize)]
69#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
70pub struct TrendCount {
71 pub value: usize,
73 pub total: usize,
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
79#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
80#[serde(rename_all = "snake_case")]
81pub enum TrendDirection {
82 Improving,
84 Declining,
86 Stable,
88}
89
90impl TrendDirection {
91 #[must_use]
93 pub const fn arrow(self) -> &'static str {
94 match self {
95 Self::Improving => "\u{2191}", Self::Declining => "\u{2193}", Self::Stable => "\u{2192}", }
99 }
100
101 #[must_use]
103 pub const fn label(self) -> &'static str {
104 match self {
105 Self::Improving => "improving",
106 Self::Declining => "declining",
107 Self::Stable => "stable",
108 }
109 }
110}