relay_event_schema/protocol/contexts/
device.rs1use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value};
2use uuid::Uuid;
3
4use crate::processor::ProcessValue;
5
6#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
11pub struct DeviceContext {
12 #[metastructure(pii = "maybe")]
14 pub name: Annotated<String>,
15
16 pub family: Annotated<String>,
21
22 pub model: Annotated<String>,
26
27 pub model_id: Annotated<String>,
31
32 pub arch: Annotated<String>,
34
35 pub battery_level: Annotated<f64>,
40
41 pub orientation: Annotated<String>,
45
46 pub manufacturer: Annotated<String>,
48
49 pub brand: Annotated<String>,
51
52 #[metastructure(pii = "maybe")]
56 pub screen_resolution: Annotated<String>,
57
58 #[metastructure(pii = "maybe")]
60 pub screen_width_pixels: Annotated<u64>,
61
62 #[metastructure(pii = "maybe")]
64 pub screen_height_pixels: Annotated<u64>,
65
66 #[metastructure(pii = "maybe")]
68 pub screen_density: Annotated<f64>,
69
70 #[metastructure(pii = "maybe")]
72 pub screen_dpi: Annotated<u64>,
73
74 pub online: Annotated<bool>,
76
77 pub charging: Annotated<bool>,
79
80 pub low_memory: Annotated<bool>,
82
83 pub simulator: Annotated<bool>,
85
86 #[metastructure(pii = "maybe")]
88 pub memory_size: Annotated<u64>,
89
90 #[metastructure(pii = "maybe")]
92 pub free_memory: Annotated<u64>,
93
94 #[metastructure(pii = "maybe")]
96 pub usable_memory: Annotated<u64>,
97
98 #[metastructure(pii = "maybe")]
100 pub storage_size: Annotated<u64>,
101
102 #[metastructure(pii = "maybe")]
104 pub free_storage: Annotated<u64>,
105
106 #[metastructure(pii = "maybe")]
108 pub external_storage_size: Annotated<u64>,
109
110 #[metastructure(pii = "maybe")]
112 pub external_free_storage: Annotated<u64>,
113
114 #[metastructure(pii = "maybe")]
116 pub boot_time: Annotated<String>,
117
118 #[metastructure(pii = "maybe")]
120 pub timezone: Annotated<String>,
121
122 #[metastructure(pii = "maybe")]
124 pub locale: Annotated<String>,
125
126 pub processor_count: Annotated<u64>,
130
131 #[metastructure(pii = "maybe")]
135 pub cpu_description: Annotated<String>,
136
137 pub processor_frequency: Annotated<u64>,
142
143 #[metastructure(pii = "maybe")]
147 pub device_type: Annotated<String>,
148
149 #[metastructure(pii = "maybe")]
153 pub battery_status: Annotated<String>,
154
155 #[metastructure(pii = "true")]
157 pub device_unique_identifier: Annotated<String>,
158
159 pub supports_vibration: Annotated<bool>,
161
162 pub supports_accelerometer: Annotated<bool>,
164
165 pub supports_gyroscope: Annotated<bool>,
167
168 pub supports_audio: Annotated<bool>,
170
171 pub supports_location_service: Annotated<bool>,
173
174 #[metastructure(pii = "maybe")]
176 pub uuid: Annotated<Uuid>,
177
178 #[metastructure(additional_properties, retain = true, pii = "maybe")]
180 pub other: Object<Value>,
181}
182
183impl super::DefaultContext for DeviceContext {
184 fn default_key() -> &'static str {
185 "device"
186 }
187
188 fn from_context(context: super::Context) -> Option<Self> {
189 match context {
190 super::Context::Device(c) => Some(*c),
191 _ => None,
192 }
193 }
194
195 fn cast(context: &super::Context) -> Option<&Self> {
196 match context {
197 super::Context::Device(c) => Some(c),
198 _ => None,
199 }
200 }
201
202 fn cast_mut(context: &mut super::Context) -> Option<&mut Self> {
203 match context {
204 super::Context::Device(c) => Some(c),
205 _ => None,
206 }
207 }
208
209 fn into_context(self) -> super::Context {
210 super::Context::Device(Box::new(self))
211 }
212}
213
214#[cfg(test)]
215mod tests {
216 use uuid::uuid;
217
218 use super::*;
219 use crate::protocol::Context;
220
221 #[test]
222 fn test_device_context_roundtrip() {
223 let json = r#"{
224 "name": "iphone",
225 "family": "iphone",
226 "model": "iphone7,3",
227 "model_id": "AH223",
228 "arch": "arm64",
229 "battery_level": 58.5,
230 "orientation": "landscape",
231 "manufacturer": "Apple",
232 "brand": "iphone",
233 "screen_resolution": "800x600",
234 "screen_width_pixels": 1920,
235 "screen_height_pixels": 1080,
236 "screen_density": 1.1,
237 "screen_dpi": 1,
238 "online": true,
239 "charging": false,
240 "low_memory": false,
241 "simulator": true,
242 "memory_size": 3137978368,
243 "free_memory": 322781184,
244 "usable_memory": 2843525120,
245 "storage_size": 63989469184,
246 "free_storage": 31994734592,
247 "external_storage_size": 2097152,
248 "external_free_storage": 2097152,
249 "boot_time": "2018-02-08T12:52:12Z",
250 "timezone": "Europe/Vienna",
251 "locale": "de-AT",
252 "processor_count": 8,
253 "cpu_description": "Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz",
254 "processor_frequency": 2400,
255 "device_type": "Handheld",
256 "battery_status": "Charging",
257 "device_unique_identifier": "1234567",
258 "supports_vibration": true,
259 "supports_accelerometer": true,
260 "supports_gyroscope": true,
261 "supports_audio": true,
262 "supports_location_service": true,
263 "uuid": "abadcade-feed-dead-beef-baddadfeeded",
264 "other": "value",
265 "type": "device"
266}"#;
267 let context = Annotated::new(Context::Device(Box::new(DeviceContext {
268 name: Annotated::new("iphone".to_string()),
269 family: Annotated::new("iphone".to_string()),
270 model: Annotated::new("iphone7,3".to_string()),
271 model_id: Annotated::new("AH223".to_string()),
272 arch: Annotated::new("arm64".to_string()),
273 battery_level: Annotated::new(58.5),
274 orientation: Annotated::new("landscape".to_string()),
275 simulator: Annotated::new(true),
276 manufacturer: Annotated::new("Apple".to_string()),
277 brand: Annotated::new("iphone".to_string()),
278 screen_resolution: Annotated::new("800x600".to_string()),
279 screen_width_pixels: Annotated::new(1920),
280 screen_height_pixels: Annotated::new(1080),
281 screen_density: Annotated::new(1.1),
282 screen_dpi: Annotated::new(1),
283 online: Annotated::new(true),
284 charging: Annotated::new(false),
285 low_memory: Annotated::new(false),
286 memory_size: Annotated::new(3_137_978_368),
287 free_memory: Annotated::new(322_781_184),
288 usable_memory: Annotated::new(2_843_525_120),
289 storage_size: Annotated::new(63_989_469_184),
290 free_storage: Annotated::new(31_994_734_592),
291 external_storage_size: Annotated::new(2_097_152),
292 external_free_storage: Annotated::new(2_097_152),
293 boot_time: Annotated::new("2018-02-08T12:52:12Z".to_string()),
294 timezone: Annotated::new("Europe/Vienna".to_string()),
295 locale: Annotated::new("de-AT".to_string()),
296 processor_count: Annotated::new(8),
297 cpu_description: Annotated::new(
298 "Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz".to_string(),
299 ),
300 processor_frequency: Annotated::new(2400),
301 device_type: Annotated::new("Handheld".to_string()),
302 battery_status: Annotated::new("Charging".to_string()),
303 device_unique_identifier: Annotated::new("1234567".to_string()),
304 supports_vibration: Annotated::new(true),
305 supports_accelerometer: Annotated::new(true),
306 supports_gyroscope: Annotated::new(true),
307 supports_audio: Annotated::new(true),
308 supports_location_service: Annotated::new(true),
309 uuid: Annotated::new(uuid!("abadcade-feed-dead-beef-baddadfeeded")),
310 other: {
311 let mut map = Object::new();
312 map.insert(
313 "other".to_string(),
314 Annotated::new(Value::String("value".to_string())),
315 );
316 map
317 },
318 })));
319
320 assert_eq!(context, Annotated::from_json(json).unwrap());
321 assert_eq!(json, context.to_json_pretty().unwrap());
322 }
323}