rocraters/ro_crate/
data_entity.rs1use crate::ro_crate::constraints::*;
7use crate::ro_crate::modify::*;
8use serde::{
9 Deserialize, Deserializer, Serialize, Serializer,
10 de::{self, MapAccess, Visitor},
11};
12use std::collections::HashMap;
13use std::fmt;
14
15#[derive(Debug, Clone)]
22pub struct DataEntity {
23 pub id: String,
25 pub type_: DataType,
27 pub dynamic_entity: Option<HashMap<String, EntityValue>>,
29}
30
31impl DynamicEntityManipulation for DataEntity {
36 fn dynamic_entity(&mut self) -> &mut Option<HashMap<String, EntityValue>> {
37 &mut self.dynamic_entity
38 }
39
40 fn dynamic_entity_immut(&self) -> &Option<HashMap<String, EntityValue>> {
41 &self.dynamic_entity
42 }
43}
44
45impl DataEntity {
46 pub fn get_property_value(&self, property: &str) -> Option<(String, EntityValue)> {
48 match property {
50 "@type" => Some((
51 self.id.clone(),
52 EntityValue::EntityDataType(self.type_.clone()),
53 )),
54 _ => self
55 .search_properties_for_value(property)
56 .map(|value| (self.id.clone(), value)),
57 }
58 }
59 pub fn find_value_details(&self, target_value: &EntityValue) -> Option<(String, String)> {
67 if let Some(dynamic_entity) = &self.dynamic_entity {
69 if let Some(key) = search_dynamic_entity_for_key(dynamic_entity, target_value) {
70 return Some((self.id.clone(), key));
71 }
72 }
73
74 None
75 }
76 pub fn get_linked_ids(&self) -> Vec<Id> {
77 let mut ids = Vec::new();
78
79 if let Some(dynamic_entity) = &self.dynamic_entity {
81 for value in dynamic_entity.values() {
82 Self::extract_ids_from_entity_value(value, &mut ids);
83 }
84 }
85
86 ids
87 }
88
89 fn extract_ids_from_entity_value(value: &EntityValue, ids: &mut Vec<Id>) {
91 match value {
92 EntityValue::EntityId(id) => {
93 ids.push(id.clone());
94 }
95 EntityValue::EntityVec(vec) => {
96 for v in vec {
97 Self::extract_ids_from_entity_value(v, ids);
98 }
99 }
100 EntityValue::EntityObject(map) => {
101 for v in map.values() {
102 Self::extract_ids_from_entity_value(v, ids);
103 }
104 }
105 EntityValue::EntityVecObject(vec_map) => {
106 for map in vec_map {
107 for v in map.values() {
108 Self::extract_ids_from_entity_value(v, ids);
109 }
110 }
111 }
112 EntityValue::NestedDynamicEntity(nested_value) => {
113 Self::extract_ids_from_entity_value(nested_value, ids);
114 }
115 _ => {}
116 }
117 }
118}
119
120impl fmt::Display for DataEntity {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(
124 f,
125 "ContextualEntity: id={}, type_={:?}, dynamic_entity={:?}",
126 self.id, self.type_, self.dynamic_entity
127 )
128 }
129}
130
131impl CustomSerialize for DataEntity {
137 fn dynamic_entity(&self) -> Option<&HashMap<String, EntityValue>> {
138 self.dynamic_entity.as_ref()
139 }
140
141 fn id(&self) -> &String {
142 &self.id
143 }
144
145 fn type_(&self) -> &DataType {
146 &self.type_
147 }
148}
149
150impl Serialize for DataEntity {
155 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
156 where
157 S: Serializer,
158 {
159 self.custom_serialize(serializer)
160 }
161}
162
163impl<'de> Deserialize<'de> for DataEntity {
174 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
175 where
176 D: Deserializer<'de>,
177 {
178 struct DataEntityVisitor;
179
180 impl<'de> Visitor<'de> for DataEntityVisitor {
181 type Value = DataEntity;
182
183 fn expecting(&self, formatter: &mut fmt::Formatter) -> std::fmt::Result {
184 formatter.write_str("a map representing a DataEntity")
185 }
186
187 fn visit_map<A>(self, mut map: A) -> Result<DataEntity, A::Error>
188 where
189 A: MapAccess<'de>,
190 {
191 let mut id = None;
192 let mut type_ = None;
193 let mut dynamic_entity: HashMap<String, EntityValue> = HashMap::new();
194
195 while let Some(key) = map.next_key::<String>()? {
196 match key.as_str() {
197 "@id" => id = Some(map.next_value()?),
198 "@type" => type_ = Some(map.next_value()?),
199 _ => {
200 let value: EntityValue = map.next_value()?;
201 dynamic_entity.insert(key, value);
202 }
203 }
204 }
205
206 let id = id.ok_or_else(|| de::Error::missing_field("@id"))?;
207 let type_ = type_.ok_or_else(|| de::Error::missing_field("@type"))?;
208
209 Ok(DataEntity {
210 id,
211 type_,
212 dynamic_entity: Some(dynamic_entity),
213 })
214 }
215 }
216
217 deserializer.deserialize_map(DataEntityVisitor)
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[test]
226 fn test_data_entity_creation() {
227 let entity = DataEntity {
228 id: "entity_id".to_string(),
229 type_: DataType::Term("ExampleType".to_string()),
230 dynamic_entity: Some(HashMap::new()),
231 };
232 assert_eq!(entity.id, "entity_id");
233 assert!(matches!(entity.type_, DataType::Term(ref t) if t == "ExampleType"));
234 assert!(entity.dynamic_entity.is_some());
235 }
236
237 #[test]
238 fn test_add_and_remove_dynamic_entity() {
239 let mut entity = DataEntity {
240 id: "entity_id".to_string(),
241 type_: DataType::Term("ExampleType".to_string()),
242 dynamic_entity: None,
243 };
244
245 entity.add_string_value("key".to_string(), "value".to_string());
247 assert_eq!(
248 entity.dynamic_entity().unwrap().get("key"),
249 Some(&EntityValue::EntityString("value".to_string()))
250 );
251
252 entity.remove_field("key");
254 assert!(entity.dynamic_entity().unwrap().get("key").is_none());
255 }
256
257 #[test]
258 fn test_serialization() {
259 let entity = DataEntity {
260 id: "entity_id".to_string(),
261 type_: DataType::Term("ExampleType".to_string()),
262 dynamic_entity: None,
263 };
264
265 let serialized = serde_json::to_string(&entity).unwrap();
266 assert!(serialized.contains("entity_id"));
267 assert!(serialized.contains("ExampleType"));
268 }
269
270 #[test]
271 fn test_deserialization() {
272 let json_data = r#"
273 {
274 "@id": "entity_id",
275 "@type": "ExampleType"
276 }
277 "#;
278 let deserialized: DataEntity = serde_json::from_str(json_data).unwrap();
279 assert_eq!(deserialized.id, "entity_id");
280 assert!(matches!(deserialized.type_, DataType::Term(ref t) if t == "ExampleType"));
281 }
282
283 #[test]
284 fn test_dynamic_entity_serialization() {
285 let mut entity = DataEntity {
286 id: "entity_id".to_string(),
287 type_: DataType::Term("ExampleType".to_string()),
288 dynamic_entity: None,
289 };
290 entity.add_string_value("key".to_string(), "value".to_string());
291
292 let serialized = serde_json::to_string(&entity).unwrap();
293 assert!(serialized.contains("\"key\":\"value\""));
294 }
295
296 #[test]
297 fn test_dynamic_entity_deserialization() {
298 let json_data = r#"
299 {
300 "@id": "entity_id",
301 "@type": "ExampleType",
302 "key": "value"
303 }
304 "#;
305 let deserialized: DataEntity = serde_json::from_str(json_data).unwrap();
306 assert_eq!(
307 deserialized.dynamic_entity.unwrap().get("key"),
308 Some(&EntityValue::EntityString("value".to_string()))
309 );
310 }
311
312 #[test]
313 fn test_deserialization_with_missing_fields() {
314 let json_data = r#"
315 {
316 "@id": "entity_id"
317 }
318 "#;
319 let result: Result<DataEntity, _> = serde_json::from_str(json_data);
320 assert!(result.is_err()); }
322}