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