memfaultd/metrics/
metric_value.rs1use eyre::Result;
5use serde::{Deserialize, Serialize, Serializer};
6use std::fmt::Display;
7
8#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
9pub struct Histogram {
10 pub min: f64,
11 pub mean: f64,
12 pub max: f64,
13}
14
15impl Histogram {
16 pub fn min(&self) -> MetricValue {
17 MetricValue::Number(self.min)
18 }
19
20 pub fn avg(&self) -> MetricValue {
21 MetricValue::Number(self.mean)
22 }
23
24 pub fn max(&self) -> MetricValue {
25 MetricValue::Number(self.max)
26 }
27}
28
29pub fn construct_histogram_value(min: f64, mean: f64, max: f64) -> Histogram {
30 Histogram { min, mean, max }
31}
32
33#[derive(Clone, Debug, PartialEq, Deserialize)]
34#[serde(untagged)]
35pub enum MetricValue {
36 Number(f64),
37 String(String),
38 Histogram(Histogram),
39 Bool(bool),
40}
41
42impl Serialize for MetricValue {
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: Serializer,
46 {
47 match self {
48 MetricValue::Number(v) => serializer.serialize_f64(*v),
49 MetricValue::String(v) => serializer.serialize_str(v.as_str()),
50 MetricValue::Histogram(histo) => histo.serialize(serializer),
51 MetricValue::Bool(v) => serializer.serialize_bool(*v),
52 }
53 }
54}
55
56impl Display for MetricValue {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 let json_value = match self {
59 MetricValue::Number(n) => serde_json::Value::Number(
60 serde_json::Number::from_f64(*n).unwrap_or(serde_json::Number::from(0)),
61 ),
62 MetricValue::String(s) => serde_json::Value::String(s.clone()),
63 MetricValue::Bool(b) => serde_json::Value::Bool(*b),
64 MetricValue::Histogram(h) => {
65 serde_json::json!({
67 "type": "histogram",
68 "avg": h.mean,
69 "min": h.min,
70 "max": h.max
71 })
72 }
73 };
74 write!(f, "{}", json_value)
75 }
76}