1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use time::OffsetDateTime;
4
5#[cfg_attr(
6 feature = "serde",
7 derive(Serialize, Deserialize),
8 serde(rename_all = "camelCase")
9)]
10#[derive(Debug, Clone, PartialEq)]
11#[non_exhaustive]
12pub struct PassMetric {
13 pub site: SiteMetric,
14}
15
16#[cfg_attr(
17 feature = "serde",
18 derive(Serialize, Deserialize),
19 serde(rename_all = "camelCase")
20)]
21#[derive(Debug, Clone, PartialEq)]
22#[non_exhaustive]
23pub struct SiteMetric {
24 pub task_id: i32,
25 pub name: String,
26 pub task_request_uri: String,
27 pub configuration: String,
28 pub site_uri: String,
29 pub config_uri: String,
30 #[cfg_attr(feature = "serde", serde(with = "crate::utils::timestamp"))]
31 pub collected: OffsetDateTime,
32 pub hardware_metrics: Vec<HardwareMetric>,
33}
34
35#[cfg_attr(
36 feature = "serde",
37 derive(Serialize, Deserialize),
38 serde(rename_all = "camelCase")
39)]
40#[derive(Debug, Clone, PartialEq)]
41#[non_exhaustive]
42pub struct HardwareMetric {
43 pub name: String,
44 pub mfg: String,
45 pub model: Option<String>,
46 #[cfg_attr(feature = "serde", serde(rename = "type"))]
47 pub hw_type: String,
48 pub metrics: Vec<ValueMetric>,
49}
50
51#[cfg_attr(
52 feature = "serde",
53 derive(Serialize, Deserialize),
54 serde(rename_all = "camelCase")
55)]
56#[derive(Debug, Clone, PartialEq)]
57#[non_exhaustive]
58pub struct ValueMetric {
59 #[cfg_attr(feature = "serde", serde(rename = "type"))]
60 pub type_string: String,
61 #[cfg_attr(feature = "serde", serde(flatten))]
62 pub value: Value,
63 pub unit: String,
64}
65
66#[cfg_attr(
67 feature = "serde",
68 derive(Serialize, Deserialize),
69 serde(rename_all = "camelCase", tag = "valueType", content = "value")
70)]
71#[derive(Debug, Clone, PartialEq, PartialOrd)]
72#[non_exhaustive]
73pub enum Value {
74 Bool(bool),
75 Float(f64),
76 Long(i64),
77 Int(i32),
78 String(String),
79}
80
81#[cfg(all(test, feature = "serde"))]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn deserialize() {
87 let json_value = r#"{
88 "site": {
89 "taskId": 1,
90 "taskRequestUri": "https://test-api.atlasground.com/api/requests/1",
91 "name": "MySite",
92 "configuration": "MySite-000A",
93 "siteUri": "https://test-api.atlasground.com/api/sites/1",
94 "configUri": "https://test-api.atlasground.com/api/configurations/1",
95 "collected": 1648733340.076,
96 "hardwareMetrics": [
97 {
98 "name": "test-hardware",
99 "mfg": "Tech",
100 "model": "1.x.x",
101 "type": "MODEM",
102 "metrics": [
103 {
104 "type": "site.hardware.modem.status",
105 "value": true,
106 "unit": "bool",
107 "valueType": "bool"
108 }
109 ]
110 },
111 {
112 "name": "test-hardware",
113 "mfg": "Tech",
114 "model": "1.x.x",
115 "type": "DIGITIZER",
116 "metrics": [
117 {
118 "type": "site.hardware.digitizer.status",
119 "value": true,
120 "unit": "bool",
121 "valueType": "bool"
122 }
123 ]
124 },
125 {
126 "name": "Site Server",
127 "mfg": "ATLAS",
128 "model": "1.x.x",
129 "type": "SUM",
130 "metrics": [
131 {
132 "type": "site.hardware.status",
133 "value": true,
134 "unit": "bool",
135 "valueType": "bool"
136 },
137 {
138 "type": "site.hardware.pass.timing",
139 "value": 3467,
140 "unit": "s",
141 "valueType": "long"
142 }
143 ]
144 }
145 ]
146 }
147}"#;
148
149 let ser: PassMetric = serde_json::from_slice(json_value.as_bytes()).unwrap();
150 let first = &ser.site.hardware_metrics[0].metrics[0];
151 assert_eq!(first.type_string.as_str(), "site.hardware.modem.status");
152 assert_eq!(&first.value, &Value::Bool(true));
153 let second = &ser.site.hardware_metrics[1].metrics[0];
154 assert_eq!(
155 second.type_string.as_str(),
156 "site.hardware.digitizer.status"
157 );
158 assert_eq!(&second.value, &Value::Bool(true));
159 let second = &ser.site.hardware_metrics[1].metrics[0];
160 assert_eq!(
161 second.type_string.as_str(),
162 "site.hardware.digitizer.status"
163 );
164 assert_eq!(&second.value, &Value::Bool(true));
165 let third = &ser.site.hardware_metrics[2].metrics[0];
166 assert_eq!(third.type_string.as_str(), "site.hardware.status");
167 assert_eq!(&third.value, &Value::Bool(true));
168 let fourth = &ser.site.hardware_metrics[2].metrics[1];
169 assert_eq!(fourth.type_string.as_str(), "site.hardware.pass.timing");
170 assert_eq!(&fourth.value, &Value::Long(3467));
171 }
172}