1#![no_std]
2#![feature(coverage_attribute)]
3#![deny(missing_docs)]
4
5extern crate alloc;
11
12pub mod geometry;
14pub mod map;
16pub mod value;
18pub mod value_impl;
20pub mod vector_point;
22
23use alloc::{string::String, vec::Vec};
24pub use geometry::*;
25pub use map::*;
26use serde::{Deserialize, Serialize};
27pub use value::*;
28pub use vector_point::*;
29
30#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
32pub enum Projection {
33 #[default]
35 S2,
36 WG,
38}
39
40#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
44pub enum Face {
45 #[default]
47 Face0 = 0,
48 Face1 = 1,
50 Face2 = 2,
52 Face3 = 3,
54 Face4 = 4,
56 Face5 = 5,
58}
59impl From<Face> for u8 {
60 fn from(face: Face) -> Self {
61 face as u8
62 }
63}
64impl From<u8> for Face {
65 fn from(face: u8) -> Self {
66 match face {
67 1 => Face::Face1,
68 2 => Face::Face2,
69 3 => Face::Face3,
70 4 => Face::Face4,
71 5 => Face::Face5,
72 _ => Face::Face0,
73 }
74 }
75}
76impl serde::Serialize for Face {
77 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: serde::Serializer,
80 {
81 serializer.serialize_u8(*self as u8)
82 }
83}
84
85impl<'de> serde::Deserialize<'de> for Face {
86 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87 where
88 D: serde::Deserializer<'de>,
89 {
90 let value = u8::deserialize(deserializer)?;
91 match value {
92 0 => Ok(Face::Face0),
93 1 => Ok(Face::Face1),
94 2 => Ok(Face::Face2),
95 3 => Ok(Face::Face3),
96 4 => Ok(Face::Face4),
97 5 => Ok(Face::Face5),
98 _ => Err(serde::de::Error::custom("Invalid face value")),
99 }
100 }
101}
102
103#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
105pub enum FeatureCollectionType {
106 #[default]
108 FeatureCollection,
109}
110impl From<&str> for FeatureCollectionType {
111 fn from(_: &str) -> Self {
112 FeatureCollectionType::FeatureCollection
113 }
114}
115
116#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
118pub enum S2FeatureCollectionType {
119 #[default]
121 S2FeatureCollection,
122}
123impl From<&str> for S2FeatureCollectionType {
124 fn from(_: &str) -> Self {
125 S2FeatureCollectionType::S2FeatureCollection
126 }
127}
128
129#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
133pub struct FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
134 #[serde(rename = "type")]
136 pub _type: FeatureCollectionType,
137 pub features: Vec<WMFeature<M, P, D>>,
139 #[serde(skip_serializing_if = "Option::is_none")]
141 pub attributions: Option<Attributions>,
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub bbox: Option<BBox>,
145}
146impl<M, P: Clone + Default, D: Clone + Default> FeatureCollection<M, P, D> {
147 pub fn new(attributions: Option<Attributions>) -> Self {
149 Self { _type: "FeatureCollection".into(), features: Vec::new(), attributions, bbox: None }
150 }
151
152 pub fn update_bbox(&mut self, bbox: BBox) {
154 let mut self_bbox = self.bbox.unwrap_or_default();
155 self_bbox = self_bbox.merge(&bbox);
156 self.bbox = Some(self_bbox);
157 }
158}
159
160#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
162pub struct S2FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue>
163{
164 #[serde(rename = "type")]
166 pub _type: S2FeatureCollectionType,
167 pub features: Vec<VectorFeature<M, P, D>>,
169 pub faces: Vec<Face>,
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub attributions: Option<Attributions>,
174 #[serde(skip_serializing_if = "Option::is_none")]
176 pub bbox: Option<BBox>,
177}
178impl<M, P: Clone + Default, D: Clone + Default> S2FeatureCollection<M, P, D> {
179 pub fn new(attributions: Option<Attributions>) -> Self {
181 Self {
182 _type: "S2FeatureCollection".into(),
183 features: Vec::new(),
184 faces: Vec::new(),
185 attributions,
186 bbox: None,
187 }
188 }
189
190 pub fn update_bbox(&mut self, bbox: BBox) {
192 let mut self_bbox = self.bbox.unwrap_or_default();
193 self_bbox = self_bbox.merge(&bbox);
194 self.bbox = Some(self_bbox);
195 }
196
197 pub fn add_face(&mut self, face: Face) {
199 if !self.faces.contains(&face) {
200 self.faces.push(face);
201 }
202 }
203}
204
205#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
209pub enum FeatureType {
210 #[default]
212 Feature,
213}
214impl From<&str> for FeatureType {
215 fn from(_: &str) -> Self {
216 FeatureType::Feature
217 }
218}
219
220#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
222pub struct Feature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
223 #[serde(rename = "type")]
225 pub _type: FeatureType,
226 #[serde(skip_serializing_if = "Option::is_none")]
228 pub id: Option<u64>,
229 pub properties: P,
231 pub geometry: Geometry<D>,
233 #[serde(skip_serializing_if = "Option::is_none")]
235 pub metadata: Option<M>,
236}
237impl<M, P: Clone + Default, D: Clone + Default> Feature<M, P, D> {
238 pub fn new(id: Option<u64>, properties: P, geometry: Geometry<D>, metadata: Option<M>) -> Self {
240 Self { _type: "Feature".into(), id, properties, geometry, metadata }
241 }
242}
243impl<M, P: Clone + Default, D: Clone + Default> Default for Feature<M, P, D> {
244 fn default() -> Self {
245 Self {
246 _type: "Feature".into(),
247 id: None,
248 properties: Default::default(),
249 geometry: Default::default(),
250 metadata: None,
251 }
252 }
253}
254
255#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
257pub enum VectorFeatureType {
258 #[default]
260 VectorFeature,
261 S2Feature,
263}
264impl From<&str> for VectorFeatureType {
265 fn from(s: &str) -> Self {
266 match s {
267 "S2Feature" => VectorFeatureType::S2Feature,
268 _ => VectorFeatureType::VectorFeature,
269 }
270 }
271}
272
273#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
275pub struct VectorFeature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
276 #[serde(rename = "type")]
278 pub _type: VectorFeatureType,
279 #[serde(skip_serializing_if = "Option::is_none")]
281 pub id: Option<u64>,
282 pub face: Face,
284 pub properties: P,
286 pub geometry: VectorGeometry<D>,
288 #[serde(skip_serializing_if = "Option::is_none")]
290 pub metadata: Option<M>,
291}
292impl<M, P: Clone + Default, D: Clone + Default> Default for VectorFeature<M, P, D> {
293 fn default() -> Self {
294 Self {
295 _type: "VectorFeature".into(),
296 face: 0.into(),
297 id: None,
298 properties: Default::default(),
299 geometry: Default::default(),
300 metadata: None,
301 }
302 }
303}
304impl<M, P: Clone + Default, D: Clone + Default> VectorFeature<M, P, D> {
305 pub fn new_wm(
307 id: Option<u64>,
308 properties: P,
309 geometry: VectorGeometry<D>,
310 metadata: Option<M>,
311 ) -> Self {
312 Self { _type: "VectorFeature".into(), face: 0.into(), id, properties, geometry, metadata }
313 }
314
315 pub fn new_s2(
317 id: Option<u64>,
318 face: Face,
319 properties: P,
320 geometry: VectorGeometry<D>,
321 metadata: Option<M>,
322 ) -> Self {
323 Self { _type: "S2Feature".into(), face, id, properties, geometry, metadata }
324 }
325
326 pub fn from_vector_feature(
328 feature: &VectorFeature<M, P, D>,
329 geometry: Option<VectorGeometry<D>>,
330 ) -> Self
331 where
332 M: Clone,
333 {
334 Self {
335 _type: feature._type.clone(),
336 id: feature.id,
337 face: feature.face,
338 properties: feature.properties.clone(),
339 geometry: geometry.unwrap_or(feature.geometry.clone()),
340 metadata: feature.metadata.clone(),
341 }
342 }
343}
344
345pub type Attributions = Map<String, String>;
351
352#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
354pub enum FeatureCollections<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
355 FeatureCollection(FeatureCollection<M, P, D>),
357 S2FeatureCollection(S2FeatureCollection<M, P, D>),
359}
360
361#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
363pub enum Features<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
364 Feature(Feature<M, P, D>),
366 VectorFeature(VectorFeature<M, P, D>),
368}
369
370#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
372#[serde(untagged)]
373pub enum WMFeature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
374 Feature(Feature<M, P, D>),
376 VectorFeature(VectorFeature<M, P, D>),
378}
379
380#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
382#[serde(untagged)]
383pub enum JSONCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
384 FeatureCollection(FeatureCollection<M, P, D>),
386 S2FeatureCollection(S2FeatureCollection<M, P, D>),
388 Feature(Feature<M, P, D>),
390 VectorFeature(VectorFeature<M, P, D>),
392}
393
394#[cfg(test)]
395mod tests {
396 use super::*;
397 use alloc::{string::ToString, vec};
398
399 #[test]
400 fn face() {
401 let face = Face::Face0;
402 assert_eq!(u8::from(face), 0);
403 let face = Face::Face1;
404 assert_eq!(u8::from(face), 1);
405 let face = Face::Face2;
406 assert_eq!(u8::from(face), 2);
407 let face = Face::Face3;
408 assert_eq!(u8::from(face), 3);
409 let face = Face::Face4;
410 assert_eq!(u8::from(face), 4);
411 let face = Face::Face5;
412 assert_eq!(u8::from(face), 5);
413
414 assert_eq!(Face::Face0, Face::from(0));
415 assert_eq!(Face::Face1, Face::from(1));
416 assert_eq!(Face::Face2, Face::from(2));
417 assert_eq!(Face::Face3, Face::from(3));
418 assert_eq!(Face::Face4, Face::from(4));
419 assert_eq!(Face::Face5, Face::from(5));
420 }
421
422 #[test]
423 fn defaults() {
424 let f: Feature = Default::default();
425 assert_eq!(f._type, "Feature".into());
426 assert_eq!(f.id, None);
427 assert_eq!(f.properties, Properties::default());
428 assert_eq!(f.geometry, Geometry::default());
429 assert_eq!(f.metadata, None);
430
431 let f: VectorFeature = Default::default();
432 assert_eq!(f._type, "VectorFeature".into());
433 assert_eq!(f.id, None);
434 assert_eq!(f.face, 0.into());
435 assert_eq!(f.properties, Properties::default());
436 assert_eq!(f.geometry, VectorGeometry::default());
437 assert_eq!(f.metadata, None);
438 }
439
440 #[test]
441 fn feature_collection_new() {
442 let mut attributions = Attributions::new();
443 attributions.insert("Open S2".to_string(), "https://opens2.com/legal/data".to_string());
444 let mut fc = FeatureCollection::<()>::new(Some(attributions.clone()));
445 assert_eq!(fc._type, FeatureCollectionType::FeatureCollection);
446 assert_eq!(fc.features.len(), 0);
447 assert_eq!(fc.attributions, Some(attributions.clone()));
448 fc.update_bbox(BBox::new(5., -2., 35., 2.2));
450 assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
451
452 let string = serde_json::to_string(&fc).unwrap();
453 assert_eq!(string, "{\"type\":\"FeatureCollection\",\"features\":[],\"attributions\":{\"Open S2\":\"https://opens2.com/legal/data\"},\"bbox\":[5.0,-2.0,35.0,2.2]}");
454 let back_to_fc: FeatureCollection = serde_json::from_str(&string).unwrap();
455 assert_eq!(back_to_fc, fc);
456 }
457
458 #[test]
459 fn s2_feature_collection_new() {
460 let mut attributions = Attributions::new();
461 attributions.insert("Open S2".to_string(), "https://opens2.com/legal/data".to_string());
462 let mut fc = S2FeatureCollection::new(Some(attributions.clone()));
463 assert_eq!(fc._type, S2FeatureCollectionType::S2FeatureCollection);
464 assert_eq!(fc.features.len(), 0);
465 assert_eq!(fc.attributions, Some(attributions.clone()));
466 fc.update_bbox(BBox::new(5., -2., 35., 2.2));
468 assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
469 fc.add_face(0.into());
471 fc.add_face(3.into());
472 assert_eq!(fc.faces, vec![0.into(), 3.into()]);
473
474 let string = serde_json::to_string(&fc).unwrap();
475 assert_eq!(string, "{\"type\":\"S2FeatureCollection\",\"features\":[],\"faces\":[0,3],\"attributions\":{\"Open S2\":\"https://opens2.com/legal/data\"},\"bbox\":[5.0,-2.0,35.0,2.2]}");
476 let back_to_fc: S2FeatureCollection = serde_json::from_str(&string).unwrap();
477 assert_eq!(back_to_fc, fc);
478 }
479
480 #[test]
481 fn feature_new() {
482 let fc: Feature = Feature::new(
483 Some(22),
484 Properties::new(),
485 Geometry::Point(PointGeometry {
486 _type: "Point".into(),
487 coordinates: Point(0.0, 0.0),
488 m_values: None,
489 bbox: None,
490 }),
491 None,
492 );
493 assert_eq!(fc.id, Some(22));
494 assert_eq!(fc._type, "Feature".into());
495 assert_eq!(
496 fc.geometry,
497 Geometry::Point(PointGeometry {
498 _type: "Point".into(),
499 coordinates: Point(0.0, 0.0),
500 m_values: None,
501 bbox: None,
502 })
503 );
504 assert_eq!(fc.properties, Properties::new());
505 assert_eq!(fc.metadata, None);
506 }
507
508 #[test]
509 fn s2_feature_new() {
510 let fc: VectorFeature = VectorFeature::new_wm(
511 Some(55),
512 Properties::new(),
513 VectorGeometry::Point(VectorPointGeometry {
514 _type: "Point".into(),
515 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
516 bbox: None,
517 is_3d: true,
518 offset: None,
519 vec_bbox: None,
520 indices: None,
521 tesselation: None,
522 }),
523 None,
524 );
525 assert_eq!(fc.id, Some(55));
526 assert_eq!(fc._type, "VectorFeature".into());
527 assert_eq!(
528 fc.geometry,
529 VectorGeometry::Point(VectorPointGeometry {
530 _type: "Point".into(),
531 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
532 bbox: None,
533 is_3d: true,
534 offset: None,
535 vec_bbox: None,
536 indices: None,
537 tesselation: None,
538 })
539 );
540 assert_eq!(fc.properties, Properties::new());
541 assert_eq!(fc.metadata, None);
542 assert_eq!(fc.face, 0.into());
543
544 #[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
547 struct MetaTest {
548 name: String,
549 value: String,
550 }
551
552 let fc = VectorFeature::<MetaTest>::new_s2(
553 Some(55),
554 3.into(),
555 Properties::new(),
556 VectorGeometry::Point(VectorPointGeometry {
557 _type: "Point".into(),
558 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
559 bbox: None,
560 is_3d: true,
561 offset: None,
562 vec_bbox: None,
563 indices: None,
564 tesselation: None,
565 }),
566 Some(MetaTest { name: "test".to_string(), value: "value".to_string() }),
567 );
568 assert_eq!(fc.id, Some(55));
569 assert_eq!(fc._type, "S2Feature".into());
570 assert_eq!(
571 fc.geometry,
572 VectorGeometry::Point(VectorPointGeometry {
573 _type: "Point".into(),
574 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
575 bbox: None,
576 is_3d: true,
577 offset: None,
578 vec_bbox: None,
579 indices: None,
580 tesselation: None,
581 })
582 );
583 assert_eq!(fc.properties, Properties::new());
584 assert_eq!(
585 fc.metadata,
586 Some(MetaTest { name: "test".to_string(), value: "value".to_string() })
587 );
588 assert_eq!(fc.face, 3.into());
589
590 let fc_to_str = serde_json::to_string(&fc).unwrap();
591 assert_eq!(
592 fc_to_str,
593 "{\"type\":\"S2Feature\",\"id\":55,\"face\":3,\"properties\":{},\"geometry\":{\"type\"\
594 :\"Point\",\"is3D\":true,\"coordinates\":{\"x\":0.0,\"y\":1.0,\"z\":3.0},\"indices\":\
595 null,\"tesselation\":null},\"metadata\":{\"name\":\"test\",\"value\":\"value\"}}"
596 );
597
598 let new_geo = VectorGeometry::Point(VectorPointGeometry {
601 _type: "Point".into(),
602 coordinates: VectorPoint { x: 5.0, y: 4.0, z: Some(-3.), m: None, t: None },
603 bbox: None,
604 is_3d: true,
605 offset: None,
606 vec_bbox: None,
607 indices: None,
608 tesselation: None,
609 });
610 let fc_clone_new_geometry =
611 VectorFeature::<MetaTest>::from_vector_feature(&fc, Some(new_geo.clone()));
612
613 assert_eq!(fc_clone_new_geometry.geometry, new_geo);
614 }
615
616 #[test]
617 fn parse_feature_multipoint() {
618 let json_string = r#"{
619 "type": "Feature",
620 "properties": {},
621 "geometry": {
622 "type": "MultiPoint",
623 "coordinates": [
624 [-13.292352825505162, 54.34883408204476],
625 [36.83102287804303, 59.56941785818924],
626 [50.34083898563978, 16.040052775278994],
627 [76.38149901912357, 35.155968522292056]
628 ]
629 }
630 }"#;
631
632 let feature: Feature = serde_json::from_str(json_string).unwrap();
633 assert_eq!(feature._type, "Feature".into());
634 assert_eq!(
635 feature.geometry,
636 Geometry::MultiPoint(MultiPointGeometry {
637 _type: "MultiPoint".into(),
638 coordinates: vec![
639 Point(-13.292352825505162, 54.34883408204476),
640 Point(36.83102287804303, 59.56941785818924),
641 Point(50.34083898563978, 16.040052775278994),
642 Point(76.38149901912357, 35.155968522292056),
643 ],
644 ..Default::default()
645 })
646 );
647
648 let back_to_str = serde_json::to_string(&feature).unwrap();
649 assert_eq!(
650 back_to_str,
651 "{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"MultiPoint\",\"\
652 coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
653 56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
654 155968522292056]]}}"
655 );
656 }
657
658 #[test]
659 fn parse_feature_linestring() {
660 let json_string = r#"{
661 "type": "Feature",
662 "properties": {},
663 "geometry": {
664 "type": "LineString",
665 "coordinates": [
666 [-13.292352825505162, 54.34883408204476],
667 [36.83102287804303, 59.56941785818924],
668 [50.34083898563978, 16.040052775278994],
669 [76.38149901912357, 35.155968522292056]
670 ]
671 }
672 }"#;
673
674 let feature: Feature = serde_json::from_str(json_string).unwrap();
675 assert_eq!(feature._type, "Feature".into());
676 assert_eq!(
677 feature.geometry,
678 Geometry::LineString(LineStringGeometry {
679 _type: "LineString".into(),
680 coordinates: vec![
681 Point(-13.292352825505162, 54.34883408204476),
682 Point(36.83102287804303, 59.56941785818924),
683 Point(50.34083898563978, 16.040052775278994),
684 Point(76.38149901912357, 35.155968522292056),
685 ],
686 ..Default::default()
687 })
688 );
689
690 let back_to_str = serde_json::to_string(&feature).unwrap();
691 assert_eq!(
692 back_to_str,
693 "{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"\
694 coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
695 56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
696 155968522292056]]}}"
697 );
698 }
699
700 #[test]
701 fn parse_vector_feature_linestring() {
702 let json_string = r#"{
703 "type": "VectorFeature",
704 "face": 0,
705 "properties": {},
706 "geometry": {
707 "type": "LineString",
708 "is3D": false,
709 "coordinates": [
710 { "x": -13.292352825505162, "y": 54.34883408204476 },
711 { "x": 36.83102287804303, "y": 59.56941785818924 },
712 { "x": 50.34083898563978, "y": 16.040052775278994 },
713 { "x": 76.38149901912357, "y": 35.155968522292056 }
714 ]
715 }
716 }"#;
717
718 let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
719 assert_eq!(feature._type, "VectorFeature".into());
720 let geometry = feature.geometry;
721 assert_eq!(
722 geometry,
723 VectorGeometry::LineString(VectorLineStringGeometry {
724 _type: VectorGeometryType::LineString,
725 is_3d: false,
726 coordinates: vec![
727 VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
728 VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
729 VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
730 VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
731 ],
732 ..Default::default()
733 })
734 )
735 }
736
737 #[test]
738 fn parse_vector_feature_multipoint() {
739 let json_string = r#"{
740 "type": "VectorFeature",
741 "face": 0,
742 "properties": {},
743 "geometry": {
744 "type": "MultiPoint",
745 "is3D": false,
746 "coordinates": [
747 { "x": -13.292352825505162, "y": 54.34883408204476 },
748 { "x": 36.83102287804303, "y": 59.56941785818924 },
749 { "x": 50.34083898563978, "y": 16.040052775278994 },
750 { "x": 76.38149901912357, "y": 35.155968522292056 }
751 ]
752 }
753 }"#;
754
755 let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
756 assert_eq!(feature._type, "VectorFeature".into());
757 let geometry = feature.geometry;
758 assert_eq!(
759 geometry,
760 VectorGeometry::MultiPoint(VectorMultiPointGeometry {
761 _type: VectorGeometryType::MultiPoint,
762 is_3d: false,
763 coordinates: vec![
764 VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
765 VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
766 VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
767 VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
768 ],
769 ..Default::default()
770 })
771 )
772 }
773
774 #[test]
775 fn serde_face() {
776 let face_0 = Face::Face0;
777 let serialized = serde_json::to_string(&face_0).unwrap();
778 assert_eq!(serialized, "0");
779 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
780 assert_eq!(deserialize, Face::Face0);
781
782 let face_1 = Face::Face1;
783 let serialized = serde_json::to_string(&face_1).unwrap();
784 assert_eq!(serialized, "1");
785 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
786 assert_eq!(deserialize, Face::Face1);
787
788 let face_2 = Face::Face2;
789 let serialized = serde_json::to_string(&face_2).unwrap();
790 assert_eq!(serialized, "2");
791 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
792 assert_eq!(deserialize, Face::Face2);
793
794 let face_3 = Face::Face3;
795 let serialized = serde_json::to_string(&face_3).unwrap();
796 assert_eq!(serialized, "3");
797 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
798 assert_eq!(deserialize, Face::Face3);
799
800 let face_4 = Face::Face4;
801 let serialized = serde_json::to_string(&face_4).unwrap();
802 assert_eq!(serialized, "4");
803 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
804 assert_eq!(deserialize, Face::Face4);
805
806 let face_5 = Face::Face5;
807 let serialized = serde_json::to_string(&face_5).unwrap();
808 assert_eq!(serialized, "5");
809 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
810 assert_eq!(deserialize, Face::Face5);
811 }
812
813 #[test]
814 #[should_panic(expected = "Invalid face value")]
815 fn serde_face_err() {
816 let _ = serde_json::from_str::<Face>("6").unwrap();
817 }
818}