everymap_core/domains/
attributes.rs1use crate::error::EveryMapResult;
2use async_trait::async_trait;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7pub struct AttributeOptions {
8 pub bbox: Option<String>,
10 pub language: Option<String>,
12 #[serde(default, skip_serializing_if = "Option::is_none")]
14 pub provider_extra: Option<serde_json::Value>,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct AttributeResponse {
20 pub data: serde_json::Value,
22}
23
24#[async_trait]
25pub trait AttributeProvider: Send + Sync {
26 async fn get_attributes(&self, options: &AttributeOptions)
27 -> EveryMapResult<AttributeResponse>;
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn test_attribute_options_default() {
36 let options = AttributeOptions::default();
37 assert!(options.bbox.is_none());
38 assert!(options.language.is_none());
39 assert!(options.provider_extra.is_none());
40 }
41
42 #[test]
43 fn test_attribute_options_with_fields() {
44 let options = AttributeOptions {
45 bbox: Some("52.0,13.0,52.5,13.5".to_string()),
46 language: Some("en".to_string()),
47 provider_extra: Some(serde_json::json!({"layer": "speed_limit"})),
48 };
49 assert_eq!(options.bbox, Some("52.0,13.0,52.5,13.5".to_string()));
50 assert_eq!(options.language, Some("en".to_string()));
51 }
52
53 #[test]
54 fn test_attribute_response_construction() {
55 let response = AttributeResponse {
56 data: serde_json::json!({"features": []}),
57 };
58 assert!(response.data.is_object());
59 }
60
61 #[test]
64 fn test_attribute_response_serde_roundtrip() {
65 let response = AttributeResponse {
66 data: serde_json::json!({
67 "features": [
68 {"id": 1, "speed_limit": 50, "road_name": "Main St"},
69 {"id": 2, "speed_limit": 30, "road_name": "School Zone"}
70 ],
71 "type": "FeatureCollection"
72 }),
73 };
74 let json = serde_json::to_string(&response).unwrap();
75 let back: AttributeResponse = serde_json::from_str(&json).unwrap();
76 assert!(back.data.is_object());
77 assert_eq!(back.data["features"].as_array().unwrap().len(), 2);
78 }
79
80 #[test]
81 fn test_attribute_response_empty_object() {
82 let response = AttributeResponse {
83 data: serde_json::json!({}),
84 };
85 let json = serde_json::to_string(&response).unwrap();
86 let back: AttributeResponse = serde_json::from_str(&json).unwrap();
87 assert!(back.data.is_object());
88 assert!(back.data.as_object().unwrap().is_empty());
89 }
90
91 #[test]
94 fn test_attribute_options_serde_roundtrip() {
95 let options = AttributeOptions {
96 bbox: Some("52.0,13.0,52.5,13.5".to_string()),
97 language: Some("en".to_string()),
98 provider_extra: Some(serde_json::json!({"layer": "speed_limit", "format": "json"})),
99 };
100 let json = serde_json::to_string(&options).unwrap();
101 let back: AttributeOptions = serde_json::from_str(&json).unwrap();
102 assert_eq!(back.bbox, Some("52.0,13.0,52.5,13.5".to_string()));
103 assert!(back.provider_extra.is_some());
104 }
105
106 #[test]
109 fn test_attribute_response_with_array_data() {
110 let response = AttributeResponse {
111 data: serde_json::json!([1, 2, 3]),
112 };
113 assert!(response.data.is_array());
114 }
115
116 #[test]
117 fn test_attribute_response_with_null_data() {
118 let response = AttributeResponse {
119 data: serde_json::Value::Null,
120 };
121 assert!(response.data.is_null());
122 }
123}