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 #[cfg(feature = "serde")]
87 fn deserialize() {
88 let json_value = r#"{
89 "site": {
90 "taskId": 1,
91 "taskRequestUri": "https://test-api.atlasground.com/api/requests/1",
92 "name": "MySite",
93 "configuration": "MySite-000A",
94 "siteUri": "https://test-api.atlasground.com/api/sites/1",
95 "configUri": "https://test-api.atlasground.com/api/configurations/1",
96 "collected": 1648733340.076,
97 "hardwareMetrics": [
98 {
99 "name": "test-hardware",
100 "mfg": "Tech",
101 "model": "1.x.x",
102 "type": "MODEM",
103 "metrics": [
104 {
105 "type": "site.hardware.modem.status",
106 "value": true,
107 "unit": "bool",
108 "valueType": "bool"
109 }
110 ]
111 },
112 {
113 "name": "test-hardware",
114 "mfg": "Tech",
115 "model": "1.x.x",
116 "type": "DIGITIZER",
117 "metrics": [
118 {
119 "type": "site.hardware.digitizer.status",
120 "value": true,
121 "unit": "bool",
122 "valueType": "bool"
123 }
124 ]
125 },
126 {
127 "name": "Site Server",
128 "mfg": "ATLAS",
129 "model": "1.x.x",
130 "type": "SUM",
131 "metrics": [
132 {
133 "type": "site.hardware.status",
134 "value": true,
135 "unit": "bool",
136 "valueType": "bool"
137 },
138 {
139 "type": "site.hardware.pass.timing",
140 "value": 3467,
141 "unit": "s",
142 "valueType": "long"
143 }
144 ]
145 }
146 ]
147 }
148}"#;
149
150 let ser: PassMetric = serde_json::from_slice(json_value.as_bytes()).unwrap();
151 let first = &ser.site.hardware_metrics[0].metrics[0];
152 assert_eq!(first.type_string.as_str(), "site.hardware.modem.status");
153 assert_eq!(&first.value, &Value::Bool(true));
154 let second = &ser.site.hardware_metrics[1].metrics[0];
155 assert_eq!(
156 second.type_string.as_str(),
157 "site.hardware.digitizer.status"
158 );
159 assert_eq!(&second.value, &Value::Bool(true));
160 let second = &ser.site.hardware_metrics[1].metrics[0];
161 assert_eq!(
162 second.type_string.as_str(),
163 "site.hardware.digitizer.status"
164 );
165 assert_eq!(&second.value, &Value::Bool(true));
166 let third = &ser.site.hardware_metrics[2].metrics[0];
167 assert_eq!(third.type_string.as_str(), "site.hardware.status");
168 assert_eq!(&third.value, &Value::Bool(true));
169 let fourth = &ser.site.hardware_metrics[2].metrics[1];
170 assert_eq!(fourth.type_string.as_str(), "site.hardware.pass.timing");
171 assert_eq!(&fourth.value, &Value::Long(3467));
172 }
173}