1use std::collections::HashMap;
2use serde::{Deserialize, Serialize};
3use crate::color::Color;
4use crate::rotation::Rotation;
5use crate::vector::Vector;
6
7#[derive(Deserialize, Serialize)]
9pub struct Element {
10 pub mesh_id: i32,
12 pub vector: Vector,
14 pub rotation: Rotation,
16 pub guid: String,
18 #[serde(rename(serialize = "type", deserialize = "type"))]
20 pub element_type: String,
21 pub color: Color,
23 #[serde(skip_serializing_if = "Option::is_none")]
30 pub face_colors: Option<Vec<i32>>,
31 pub info: HashMap<String, String>
33}
34
35impl PartialEq for Element {
36 fn eq(&self, other: &Self) -> bool {
37 if self.mesh_id != other.mesh_id {
38 return false;
39 }
40 if self.vector != other.vector {
41 return false;
42 }
43 if self.rotation != other.rotation {
44 return false;
45 }
46 if self.guid != other.guid {
47 return false;
48 }
49 if self.element_type != other.element_type {
50 return false;
51 }
52 if self.color != other.color {
53 return false;
54 }
55 if self.face_colors.is_none() && other.face_colors.is_none() {
56
57 } else {
58 if self.face_colors.is_some() && other.face_colors.is_some() {
59 let self_face_colors_unpacked = self.face_colors.as_ref().unwrap();
60 let other_face_colors_unpacked = other.face_colors.as_ref().unwrap();
61 if self_face_colors_unpacked.len() != other_face_colors_unpacked.len() {
62 return false;
63 }
64 for i in 0..self_face_colors_unpacked.len() {
65 if self_face_colors_unpacked[i] != other_face_colors_unpacked[i] {
66 return false;
67 }
68 }
69 } else {
70 return false;
71 }
72 }
73
74 if !self.info.eq(&other.info) {
75 return false;
76 }
77
78 true
79 }
80}
81
82impl Element {
83 pub fn new(mesh_id: i32, vector: Vector, rotation: Rotation, guid: String, element_type: String,
85 color: Color, face_colors: Option<Vec<i32>>, info: HashMap<String, String>)
86 -> Element { Element { mesh_id, vector, rotation, guid, element_type, color, face_colors, info } }
87}
88
89#[cfg(test)]
90mod tests {
91 use serde_json::to_string;
92 use serde_json::from_str;
93 use super::*;
94
95 fn get_blue_test_element() -> Element {
96 let mut info: HashMap<String, String> = HashMap::new();
97 info.insert(String::from("Key"), String::from("Value"));
98
99 Element::new(
100 4,
101 Vector::new(0.2, 0.3, 0.4),
102 Rotation::new(1.0, 1.5, 2.0, 2.5),
103 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
104 String::from("Plate"),
105 Color::new(0,0,255,0),
106 None,
107 info.clone(),
108 )
109 }
110
111 fn get_face_colored_test_element() -> Element {
112 let mut info: HashMap<String, String> = HashMap::new();
113 info.insert(String::from("Key"), String::from("Value"));
114
115 Element::new(
116 0,
117 Vector::new(0.0, 0.0, 0.0),
118 Rotation::new(0.0, 0.0, 0.0, 1.0),
119 String::from("3028896f-cd51-4b3a-be54-08841b4e9081"),
120 String::from("Cube"),
121 Color::new(0,0,255,0),
122 Some(vec![
123 255, 105, 180, 150, 255, 192, 203, 255, 53, 57, 53, 255, 0, 0, 0, 255, 243, 229, 171, 255, 255, 255, 0, 255, 9, 121, 105, 255, 0, 128, 0, 255, 0, 255, 255, 255, 0, 0, 255, 255, 226, 223, 210, 255, 255, 255, 255, 255, ]),
147 info.clone(),
148 )
149 }
150
151 #[test]
152 fn test_new_without_face_colors() {
153 let mut info: HashMap<String, String> = HashMap::new();
154 info.insert(String::from("Key"), String::from("Value"));
155
156 let result = get_blue_test_element();
157
158 assert_eq!(result.mesh_id, 4);
159 assert_eq!(Vector::new(0.2, 0.3, 0.4).eq(&result.vector), true);
160 assert_eq!(Rotation::new(1.0, 1.5, 2.0, 2.5).eq(&result.rotation), true);
161 assert_eq!(String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353").eq(&result.guid), true);
162 assert_eq!(String::from("Plate").eq(&result.element_type), true);
163 assert_eq!(Color::new(0,0,255,0).eq(&result.color), true);
164 assert_eq!(result.face_colors.is_none(), true);
165 assert_eq!(result.face_colors.is_some(), false);
166 assert_eq!(info.eq(&result.info), true);
167 }
168
169 #[test]
170 fn test_new_with_face_colors() {
171 let mut info: HashMap<String, String> = HashMap::new();
172 info.insert(String::from("Key"), String::from("Value"));
173 let expected_face_colors = vec![
174 255, 105, 180, 150, 255, 192, 203, 255, 53, 57, 53, 255, 0, 0, 0, 255, 243, 229, 171, 255, 255, 255, 0, 255, 9, 121, 105, 255, 0, 128, 0, 255, 0, 255, 255, 255, 0, 0, 255, 255, 226, 223, 210, 255, 255, 255, 255, 255, ];
198
199 let result = get_face_colored_test_element();
200
201 assert_eq!(result.mesh_id, 0);
202 assert_eq!(Vector::new(0.0, 0.0, 0.0).eq(&result.vector), true);
203 assert_eq!(Rotation::new(0.0, 0.0, 0.0, 1.0).eq(&result.rotation), true);
204 assert_eq!(String::from("3028896f-cd51-4b3a-be54-08841b4e9081").eq(&result.guid), true);
205 assert_eq!(String::from("Cube").eq(&result.element_type), true);
206 assert_eq!(Color::new(0,0,255,0).eq(&result.color), true);
207 assert_eq!(result.face_colors.is_none(), false);
208 assert_eq!(result.face_colors.is_some(), true);
209 let face_colors_unpacked = result.face_colors.as_ref().unwrap();
210 assert_eq!(face_colors_unpacked.len(), expected_face_colors.len());
211 for i in 0..face_colors_unpacked.len() {
212 assert_eq!(face_colors_unpacked[i], expected_face_colors[i]);
213 }
214 assert_eq!(info.eq(&result.info), true);
215 }
216
217 #[test]
218 fn test_partial_eq_without_face_colors_true(){
219 let a = get_blue_test_element();
220 let b = get_blue_test_element();
221 assert_eq!(a.eq(&b), true);
222 assert_eq!(b.eq(&a), true);
223 }
224
225 #[test]
226 fn test_partial_eq_without_face_colors_different_mesh_id(){
227 let a = get_blue_test_element();
228
229 let mut info: HashMap<String, String> = HashMap::new();
230 info.insert(String::from("Key"), String::from("Value"));
231
232 let b = Element::new(
233 3, Vector::new(0.2, 0.3, 0.4),
235 Rotation::new(1.0, 1.5, 2.0, 2.5),
236 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
237 String::from("Plate"),
238 Color::new(0,0,255,0),
239 None,
240 info.clone(),
241 );
242
243 assert_eq!(a.eq(&b), false);
244 assert_eq!(b.eq(&a), false);
245 }
246
247 #[test]
248 fn test_partial_eq_without_face_colors_different_vector(){
249 let a = get_blue_test_element();
250
251 let mut info: HashMap<String, String> = HashMap::new();
252 info.insert(String::from("Key"), String::from("Value"));
253
254 let b = Element::new(
255 4,
256 Vector::new(0.1, 0.3, 0.4), Rotation::new(1.0, 1.5, 2.0, 2.5),
258 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
259 String::from("Plate"),
260 Color::new(0,0,255,0),
261 None,
262 info.clone(),
263 );
264
265 assert_eq!(a.eq(&b), false);
266 assert_eq!(b.eq(&a), false);
267 }
268
269 #[test]
270 fn test_partial_eq_without_face_colors_different_rotation(){
271 let a = get_blue_test_element();
272
273 let mut info: HashMap<String, String> = HashMap::new();
274 info.insert(String::from("Key"), String::from("Value"));
275
276 let b = Element::new(
277 4,
278 Vector::new(0.2, 0.3, 0.4),
279 Rotation::new(1.0, -0.5, 2.0, 2.5), String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
281 String::from("Plate"),
282 Color::new(0,0,255,0),
283 None,
284 info.clone(),
285 );
286
287 assert_eq!(a.eq(&b), false);
288 assert_eq!(b.eq(&a), false);
289 }
290
291 #[test]
292 fn test_partial_eq_without_face_colors_different_guid(){
293 let a = get_blue_test_element();
294
295 let mut info: HashMap<String, String> = HashMap::new();
296 info.insert(String::from("Key"), String::from("Value"));
297
298 let b = Element::new(
299 4,
300 Vector::new(0.2, 0.3, 0.4),
301 Rotation::new(1.0, 1.5, 2.0, 2.5),
302 String::from("b34a1674-e680-40f2-baa9-0e9b017bea14"), String::from("Plate"),
304 Color::new(0,0,255,0),
305 None,
306 info.clone(),
307 );
308
309 assert_eq!(a.eq(&b), false);
310 assert_eq!(b.eq(&a), false);
311 }
312
313 #[test]
314 fn test_partial_eq_without_face_colors_different_type(){
315 let a = get_blue_test_element();
316
317 let mut info: HashMap<String, String> = HashMap::new();
318 info.insert(String::from("Key"), String::from("Value"));
319
320 let b = Element::new(
321 4,
322 Vector::new(0.2, 0.3, 0.4),
323 Rotation::new(1.0, 1.5, 2.0, 2.5),
324 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
325 String::from("Another one"), Color::new(0,0,255,0),
327 None,
328 info.clone(),
329 );
330
331 assert_eq!(a.eq(&b), false);
332 assert_eq!(b.eq(&a), false);
333 }
334
335 #[test]
336 fn test_partial_eq_without_face_colors_different_color(){
337 let a = get_blue_test_element();
338
339 let mut info: HashMap<String, String> = HashMap::new();
340 info.insert(String::from("Key"), String::from("Value"));
341
342 let b = Element::new(
343 4,
344 Vector::new(0.2, 0.3, 0.4),
345 Rotation::new(1.0, 1.5, 2.0, 2.5),
346 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
347 String::from("Plate"),
348 Color::new(55,0,255,0), None,
350 info.clone(),
351 );
352
353 assert_eq!(a.eq(&b), false);
354 assert_eq!(b.eq(&a), false);
355 }
356
357 #[test]
358 fn test_partial_eq_without_face_colors_existing_face_colors(){
359 let a = get_blue_test_element();
360
361 let mut info: HashMap<String, String> = HashMap::new();
362 info.insert(String::from("Key"), String::from("Value"));
363
364 let b = Element::new(
365 4,
366 Vector::new(0.2, 0.3, 0.4),
367 Rotation::new(1.0, 1.5, 2.0, 2.5),
368 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
369 String::from("Plate"),
370 Color::new(0,0,255,0),
371 Some(vec![255, 0, 0, 0]), info.clone(),
373 );
374
375 assert_eq!(a.eq(&b), false);
376 assert_eq!(b.eq(&a), false);
377 }
378
379 #[test]
380 fn test_partial_eq_without_face_colors_different_face_colors(){
381 let a = get_face_colored_test_element();
382
383 let mut info: HashMap<String, String> = HashMap::new();
384 info.insert(String::from("Key"), String::from("Value"));
385
386 let b = Element::new(
387 0,
388 Vector::new(0.0, 0.0, 0.0),
389 Rotation::new(0.0, 0.0, 0.0, 1.0),
390 String::from("3028896f-cd51-4b3a-be54-08841b4e9081"),
391 String::from("Cube"),
392 Color::new(0,0,255,0),
393 Some(vec![
394 255, 105, 180, 150, 255, 192, 203, 255, 53, 57, 53, 255, 1, 0, 0, 255, 243, 229, 171, 255, 255, 255, 0, 255, 9, 121, 105, 255, 0, 128, 0, 255, 0, 255, 255, 255, 0, 0, 255, 255, 226, 223, 210, 255, 255, 255, 255, 255, ]),
418 info.clone(),
419 );
420
421 assert_eq!(a.eq(&b), false);
422 assert_eq!(b.eq(&a), false);
423 }
424
425 #[test]
426 fn test_partial_eq_without_face_colors_different_face_colors_count(){
427 let a = get_face_colored_test_element();
428
429 let mut info: HashMap<String, String> = HashMap::new();
430 info.insert(String::from("Key"), String::from("Value"));
431
432 let b = Element::new(
433 0,
434 Vector::new(0.0, 0.0, 0.0),
435 Rotation::new(0.0, 0.0, 0.0, 1.0),
436 String::from("3028896f-cd51-4b3a-be54-08841b4e9081"),
437 String::from("Cube"),
438 Color::new(0,0,255,0),
439 Some(vec![
440 255, 105, 180, 150, 255, 192, 203, 255, 53, 57, 53, 255, 1, 0, 0, 255, 243, 229, 171, 255, 255, 255, 0, 255, 9, 121, 105, 255, 0, 128, 0, 255, 0, 255, 255, 255, 0, 0, 255, 255, 226, 223, 210, 255, 255, 255, 255, ]),
464 info.clone(),
465 );
466
467 assert_eq!(a.eq(&b), false);
468 assert_eq!(b.eq(&a), false);
469 }
470
471 #[test]
472 fn test_partial_eq_without_face_colors_different_info_value(){
473 let a = get_blue_test_element();
474
475 let mut info: HashMap<String, String> = HashMap::new();
476 info.insert(String::from("Key"), String::from("Another value")); let b = Element::new(
479 4,
480 Vector::new(0.2, 0.3, 0.4),
481 Rotation::new(1.0, 1.5, 2.0, 2.5),
482 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
483 String::from("Plate"),
484 Color::new(0,0,255,0),
485 None,
486 info.clone(),
487 );
488
489 assert_eq!(a.eq(&b), false);
490 assert_eq!(b.eq(&a), false);
491 }
492
493 #[test]
494 fn test_partial_eq_without_face_colors_different_info_key(){
495 let a = get_blue_test_element();
496
497 let mut info: HashMap<String, String> = HashMap::new();
498 info.insert(String::from("Another key"), String::from("Value")); let b = Element::new(
501 4,
502 Vector::new(0.2, 0.3, 0.4),
503 Rotation::new(1.0, 1.5, 2.0, 2.5),
504 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
505 String::from("Plate"),
506 Color::new(0,0,255,0),
507 None,
508 info.clone(),
509 );
510
511 assert_eq!(a.eq(&b), false);
512 assert_eq!(b.eq(&a), false);
513 }
514
515 #[test]
516 fn test_partial_eq_without_face_colors_different_info_length(){
517 let a = get_blue_test_element();
518
519 let mut info: HashMap<String, String> = HashMap::new();
520 info.insert(String::from("Key"), String::from("Value"));
521 info.insert(String::from("Another key"), String::from("Another value")); let b = Element::new(
524 4,
525 Vector::new(0.2, 0.3, 0.4),
526 Rotation::new(1.0, 1.5, 2.0, 2.5),
527 String::from("b8a7a2ed-0c30-4c20-867e-baa1ef7b8353"),
528 String::from("Plate"),
529 Color::new(0,0,255,0),
530 None,
531 info.clone(),
532 );
533
534 assert_eq!(a.eq(&b), false);
535 assert_eq!(b.eq(&a), false);
536 }
537
538 #[test]
539 fn test_partial_eq_with_face_colors_true(){
540 let a = get_face_colored_test_element();
541 let b = get_face_colored_test_element();
542 assert_eq!(a.eq(&b), true);
543 assert_eq!(b.eq(&a), true);
544 }
545
546 #[test]
547 fn test_to_json_without_face_colors() {
548 let input = get_blue_test_element();
549 let input_serialized = to_string(&input);
550 assert_eq!(input_serialized.is_ok(), true);
551 let input_serialized_string = input_serialized.ok().unwrap();
552 assert_eq!(input_serialized_string, "{\"mesh_id\":4,\"vector\":{\"x\":0.2,\"y\":0.3,\"z\":0.4},\"rotation\":{\"qx\":1.0,\"qy\":1.5,\"qz\":2.0,\"qw\":2.5},\"guid\":\"b8a7a2ed-0c30-4c20-867e-baa1ef7b8353\",\"type\":\"Plate\",\"color\":{\"r\":0,\"g\":0,\"b\":255,\"a\":0},\"info\":{\"Key\":\"Value\"}}");
553 }
554
555 #[test]
556 fn test_from_json_without_face_colors() {
557 let json = "{\"mesh_id\":4,\"vector\":{\"x\":0.2,\"y\":0.3,\"z\":0.4},\"rotation\":{\"qx\":1.0,\"qy\":1.5,\"qz\":2.0,\"qw\":2.5},\"guid\":\"b8a7a2ed-0c30-4c20-867e-baa1ef7b8353\",\"type\":\"Plate\",\"color\":{\"r\":0,\"g\":0,\"b\":255,\"a\":0},\"info\":{\"Key\":\"Value\"}}";
558 let actual_result = from_str::<Element>(json);
559 assert_eq!(actual_result.is_ok(), true);
561 let actual = actual_result.ok().unwrap();
562 let expected = get_blue_test_element();
563 assert_eq!(expected.eq(&actual), true);
564 }
565
566 #[test]
567 fn test_to_json_with_face_colors() {
568 let input = get_face_colored_test_element();
569 let input_serialized = to_string(&input);
570 assert_eq!(input_serialized.is_ok(), true);
571 let input_serialized_string = input_serialized.ok().unwrap();
572 assert_eq!(input_serialized_string, "{\"mesh_id\":0,\"vector\":{\"x\":0.0,\"y\":0.0,\"z\":0.0},\"rotation\":{\"qx\":0.0,\"qy\":0.0,\"qz\":0.0,\"qw\":1.0},\"guid\":\"3028896f-cd51-4b3a-be54-08841b4e9081\",\"type\":\"Cube\",\"color\":{\"r\":0,\"g\":0,\"b\":255,\"a\":0},\"face_colors\":[255,105,180,150,255,192,203,255,53,57,53,255,0,0,0,255,243,229,171,255,255,255,0,255,9,121,105,255,0,128,0,255,0,255,255,255,0,0,255,255,226,223,210,255,255,255,255,255],\"info\":{\"Key\":\"Value\"}}");
573 }
574
575 #[test]
576 fn test_from_json_with_face_colors() {
577 let json = "{\"mesh_id\":0,\"vector\":{\"x\":0.0,\"y\":0.0,\"z\":0.0},\"rotation\":{\"qx\":0.0,\"qy\":0.0,\"qz\":0.0,\"qw\":1.0},\"guid\":\"3028896f-cd51-4b3a-be54-08841b4e9081\",\"type\":\"Cube\",\"color\":{\"r\":0,\"g\":0,\"b\":255,\"a\":0},\"face_colors\":[255,105,180,150,255,192,203,255,53,57,53,255,0,0,0,255,243,229,171,255,255,255,0,255,9,121,105,255,0,128,0,255,0,255,255,255,0,0,255,255,226,223,210,255,255,255,255,255],\"info\":{\"Key\":\"Value\"}}";
578 let actual_result = from_str::<Element>(json);
579 assert_eq!(actual_result.is_ok(), true);
581 let actual = actual_result.ok().unwrap();
582 let expected = get_face_colored_test_element();
583 assert_eq!(expected.eq(&actual), true);
584 }
585}