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: MValueCompatible = Properties, D: MValueCompatible = MValue>
134{
135 #[serde(rename = "type")]
137 pub _type: FeatureCollectionType,
138 pub features: Vec<WMFeature<M, P, D>>,
140 #[serde(skip_serializing_if = "Option::is_none")]
142 pub attributions: Option<Attributions>,
143 #[serde(skip_serializing_if = "Option::is_none")]
145 pub bbox: Option<BBox>,
146}
147impl<M, P: MValueCompatible, D: MValueCompatible> FeatureCollection<M, P, D> {
148 pub fn new(attributions: Option<Attributions>) -> Self {
150 Self { _type: "FeatureCollection".into(), features: Vec::new(), attributions, bbox: None }
151 }
152
153 pub fn update_bbox(&mut self, bbox: BBox) {
155 let mut self_bbox = self.bbox.unwrap_or_default();
156 self_bbox = self_bbox.merge(&bbox);
157 self.bbox = Some(self_bbox);
158 }
159}
160
161#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
163pub struct S2FeatureCollection<
164 M = (),
165 P: MValueCompatible = Properties,
166 D: MValueCompatible = MValue,
167> {
168 #[serde(rename = "type")]
170 pub _type: S2FeatureCollectionType,
171 pub features: Vec<VectorFeature<M, P, D>>,
173 pub faces: Vec<Face>,
175 #[serde(skip_serializing_if = "Option::is_none")]
177 pub attributions: Option<Attributions>,
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub bbox: Option<BBox>,
181}
182impl<M, P: MValueCompatible, D: MValueCompatible> S2FeatureCollection<M, P, D> {
183 pub fn new(attributions: Option<Attributions>) -> Self {
185 Self {
186 _type: "S2FeatureCollection".into(),
187 features: Vec::new(),
188 faces: Vec::new(),
189 attributions,
190 bbox: None,
191 }
192 }
193
194 pub fn update_bbox(&mut self, bbox: BBox) {
196 let mut self_bbox = self.bbox.unwrap_or_default();
197 self_bbox = self_bbox.merge(&bbox);
198 self.bbox = Some(self_bbox);
199 }
200
201 pub fn add_face(&mut self, face: Face) {
203 if !self.faces.contains(&face) {
204 self.faces.push(face);
205 }
206 }
207}
208
209#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
213pub enum FeatureType {
214 #[default]
216 Feature,
217}
218impl From<&str> for FeatureType {
219 fn from(_: &str) -> Self {
220 FeatureType::Feature
221 }
222}
223
224#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
226pub struct Feature<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue> {
227 #[serde(rename = "type")]
229 pub _type: FeatureType,
230 #[serde(skip_serializing_if = "Option::is_none")]
232 pub id: Option<u64>,
233 pub properties: P,
235 pub geometry: Geometry<D>,
237 #[serde(skip_serializing_if = "Option::is_none")]
239 pub metadata: Option<M>,
240}
241impl<M, P: MValueCompatible, D: MValueCompatible> Feature<M, P, D> {
242 pub fn new(id: Option<u64>, properties: P, geometry: Geometry<D>, metadata: Option<M>) -> Self {
244 Self { _type: "Feature".into(), id, properties, geometry, metadata }
245 }
246}
247impl<M, P: MValueCompatible, D: MValueCompatible> Default for Feature<M, P, D> {
248 fn default() -> Self {
249 Self {
250 _type: "Feature".into(),
251 id: None,
252 properties: Default::default(),
253 geometry: Default::default(),
254 metadata: None,
255 }
256 }
257}
258
259#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
261pub enum VectorFeatureType {
262 #[default]
264 VectorFeature,
265 S2Feature,
267}
268impl From<&str> for VectorFeatureType {
269 fn from(s: &str) -> Self {
270 match s {
271 "S2Feature" => VectorFeatureType::S2Feature,
272 _ => VectorFeatureType::VectorFeature,
273 }
274 }
275}
276
277#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
279pub struct VectorFeature<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue> {
280 #[serde(rename = "type")]
282 pub _type: VectorFeatureType,
283 #[serde(skip_serializing_if = "Option::is_none")]
285 pub id: Option<u64>,
286 pub face: Face,
288 pub properties: P,
290 pub geometry: VectorGeometry<D>,
292 #[serde(skip_serializing_if = "Option::is_none")]
294 pub metadata: Option<M>,
295}
296impl<M, P: MValueCompatible, D: MValueCompatible> Default for VectorFeature<M, P, D> {
297 fn default() -> Self {
298 Self {
299 _type: "VectorFeature".into(),
300 face: 0.into(),
301 id: None,
302 properties: Default::default(),
303 geometry: Default::default(),
304 metadata: None,
305 }
306 }
307}
308impl<M, P: MValueCompatible, D: MValueCompatible> VectorFeature<M, P, D> {
309 pub fn new_wm(
311 id: Option<u64>,
312 properties: P,
313 geometry: VectorGeometry<D>,
314 metadata: Option<M>,
315 ) -> Self {
316 Self { _type: "VectorFeature".into(), face: 0.into(), id, properties, geometry, metadata }
317 }
318
319 pub fn new_s2(
321 id: Option<u64>,
322 face: Face,
323 properties: P,
324 geometry: VectorGeometry<D>,
325 metadata: Option<M>,
326 ) -> Self {
327 Self { _type: "S2Feature".into(), face, id, properties, geometry, metadata }
328 }
329
330 pub fn from_vector_feature(
332 feature: &VectorFeature<M, P, D>,
333 geometry: Option<VectorGeometry<D>>,
334 ) -> Self
335 where
336 M: Clone,
337 {
338 Self {
339 _type: feature._type.clone(),
340 id: feature.id,
341 face: feature.face,
342 properties: feature.properties.clone(),
343 geometry: geometry.unwrap_or(feature.geometry.clone()),
344 metadata: feature.metadata.clone(),
345 }
346 }
347}
348
349pub type Attributions = Map<String, String>;
355
356#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
358pub enum FeatureCollections<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue>
359{
360 FeatureCollection(FeatureCollection<M, P, D>),
362 S2FeatureCollection(S2FeatureCollection<M, P, D>),
364}
365
366#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
368pub enum Features<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue> {
369 Feature(Feature<M, P, D>),
371 VectorFeature(VectorFeature<M, P, D>),
373}
374
375#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
377#[serde(untagged)]
378pub enum WMFeature<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue> {
379 Feature(Feature<M, P, D>),
381 VectorFeature(VectorFeature<M, P, D>),
383}
384
385#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
387#[serde(untagged)]
388pub enum JSONCollection<M = (), P: MValueCompatible = Properties, D: MValueCompatible = MValue> {
389 FeatureCollection(FeatureCollection<M, P, D>),
391 S2FeatureCollection(S2FeatureCollection<M, P, D>),
393 Feature(Feature<M, P, D>),
395 VectorFeature(VectorFeature<M, P, D>),
397}
398
399#[cfg(test)]
400mod tests {
401 use super::*;
402 use alloc::{string::ToString, vec};
403
404 #[test]
405 fn face() {
406 let face = Face::Face0;
407 assert_eq!(u8::from(face), 0);
408 let face = Face::Face1;
409 assert_eq!(u8::from(face), 1);
410 let face = Face::Face2;
411 assert_eq!(u8::from(face), 2);
412 let face = Face::Face3;
413 assert_eq!(u8::from(face), 3);
414 let face = Face::Face4;
415 assert_eq!(u8::from(face), 4);
416 let face = Face::Face5;
417 assert_eq!(u8::from(face), 5);
418
419 assert_eq!(Face::Face0, Face::from(0));
420 assert_eq!(Face::Face1, Face::from(1));
421 assert_eq!(Face::Face2, Face::from(2));
422 assert_eq!(Face::Face3, Face::from(3));
423 assert_eq!(Face::Face4, Face::from(4));
424 assert_eq!(Face::Face5, Face::from(5));
425 }
426
427 #[test]
428 fn defaults() {
429 let f: Feature = Default::default();
430 assert_eq!(f._type, "Feature".into());
431 assert_eq!(f.id, None);
432 assert_eq!(f.properties, Properties::default());
433 assert_eq!(f.geometry, Geometry::default());
434 assert_eq!(f.metadata, None);
435
436 let f: VectorFeature = Default::default();
437 assert_eq!(f._type, "VectorFeature".into());
438 assert_eq!(f.id, None);
439 assert_eq!(f.face, 0.into());
440 assert_eq!(f.properties, Properties::default());
441 assert_eq!(f.geometry, VectorGeometry::default());
442 assert_eq!(f.metadata, None);
443 }
444
445 #[test]
446 fn feature_collection_new() {
447 let mut attributions = Attributions::new();
448 attributions.insert("Open S2".to_string(), "https://opens2.com/legal/data".to_string());
449 let mut fc = FeatureCollection::<()>::new(Some(attributions.clone()));
450 assert_eq!(fc._type, FeatureCollectionType::FeatureCollection);
451 assert_eq!(fc.features.len(), 0);
452 assert_eq!(fc.attributions, Some(attributions.clone()));
453 fc.update_bbox(BBox::new(5., -2., 35., 2.2));
455 assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
456
457 let string = serde_json::to_string(&fc).unwrap();
458 assert_eq!(string, "{\"type\":\"FeatureCollection\",\"features\":[],\"attributions\":{\"Open S2\":\"https://opens2.com/legal/data\"},\"bbox\":[5.0,-2.0,35.0,2.2]}");
459 let back_to_fc: FeatureCollection = serde_json::from_str(&string).unwrap();
460 assert_eq!(back_to_fc, fc);
461 }
462
463 #[test]
464 fn s2_feature_collection_new() {
465 let mut attributions = Attributions::new();
466 attributions.insert("Open S2".to_string(), "https://opens2.com/legal/data".to_string());
467 let mut fc = S2FeatureCollection::new(Some(attributions.clone()));
468 assert_eq!(fc._type, S2FeatureCollectionType::S2FeatureCollection);
469 assert_eq!(fc.features.len(), 0);
470 assert_eq!(fc.attributions, Some(attributions.clone()));
471 fc.update_bbox(BBox::new(5., -2., 35., 2.2));
473 assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
474 fc.add_face(0.into());
476 fc.add_face(3.into());
477 assert_eq!(fc.faces, vec![0.into(), 3.into()]);
478
479 let string = serde_json::to_string(&fc).unwrap();
480 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]}");
481 let back_to_fc: S2FeatureCollection = serde_json::from_str(&string).unwrap();
482 assert_eq!(back_to_fc, fc);
483 }
484
485 #[test]
486 fn feature_new() {
487 let fc: Feature = Feature::new(
488 Some(22),
489 Properties::new(),
490 Geometry::Point(PointGeometry {
491 _type: "Point".into(),
492 coordinates: Point(0.0, 0.0),
493 m_values: None,
494 bbox: None,
495 }),
496 None,
497 );
498 assert_eq!(fc.id, Some(22));
499 assert_eq!(fc._type, "Feature".into());
500 assert_eq!(
501 fc.geometry,
502 Geometry::Point(PointGeometry {
503 _type: "Point".into(),
504 coordinates: Point(0.0, 0.0),
505 m_values: None,
506 bbox: None,
507 })
508 );
509 assert_eq!(fc.properties, Properties::new());
510 assert_eq!(fc.metadata, None);
511 }
512
513 #[test]
514 fn s2_feature_new() {
515 let fc: VectorFeature = VectorFeature::new_wm(
516 Some(55),
517 Properties::new(),
518 VectorGeometry::Point(VectorPointGeometry {
519 _type: "Point".into(),
520 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
521 bbox: None,
522 is_3d: true,
523 offset: None,
524 vec_bbox: None,
525 indices: None,
526 tesselation: None,
527 }),
528 None,
529 );
530 assert_eq!(fc.id, Some(55));
531 assert_eq!(fc._type, "VectorFeature".into());
532 assert_eq!(
533 fc.geometry,
534 VectorGeometry::Point(VectorPointGeometry {
535 _type: "Point".into(),
536 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
537 bbox: None,
538 is_3d: true,
539 offset: None,
540 vec_bbox: None,
541 indices: None,
542 tesselation: None,
543 })
544 );
545 assert_eq!(fc.properties, Properties::new());
546 assert_eq!(fc.metadata, None);
547 assert_eq!(fc.face, 0.into());
548
549 #[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
552 struct MetaTest {
553 name: String,
554 value: String,
555 }
556
557 let fc = VectorFeature::<MetaTest>::new_s2(
558 Some(55),
559 3.into(),
560 Properties::new(),
561 VectorGeometry::Point(VectorPointGeometry {
562 _type: "Point".into(),
563 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
564 bbox: None,
565 is_3d: true,
566 offset: None,
567 vec_bbox: None,
568 indices: None,
569 tesselation: None,
570 }),
571 Some(MetaTest { name: "test".to_string(), value: "value".to_string() }),
572 );
573 assert_eq!(fc.id, Some(55));
574 assert_eq!(fc._type, "S2Feature".into());
575 assert_eq!(
576 fc.geometry,
577 VectorGeometry::Point(VectorPointGeometry {
578 _type: "Point".into(),
579 coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
580 bbox: None,
581 is_3d: true,
582 offset: None,
583 vec_bbox: None,
584 indices: None,
585 tesselation: None,
586 })
587 );
588 assert_eq!(fc.properties, Properties::new());
589 assert_eq!(
590 fc.metadata,
591 Some(MetaTest { name: "test".to_string(), value: "value".to_string() })
592 );
593 assert_eq!(fc.face, 3.into());
594
595 let fc_to_str = serde_json::to_string(&fc).unwrap();
596 assert_eq!(
597 fc_to_str,
598 "{\"type\":\"S2Feature\",\"id\":55,\"face\":3,\"properties\":{},\"geometry\":{\"type\"\
599 :\"Point\",\"is3D\":true,\"coordinates\":{\"x\":0.0,\"y\":1.0,\"z\":3.0},\"indices\":\
600 null,\"tesselation\":null},\"metadata\":{\"name\":\"test\",\"value\":\"value\"}}"
601 );
602
603 let new_geo = VectorGeometry::Point(VectorPointGeometry {
606 _type: "Point".into(),
607 coordinates: VectorPoint { x: 5.0, y: 4.0, z: Some(-3.), m: None, t: None },
608 bbox: None,
609 is_3d: true,
610 offset: None,
611 vec_bbox: None,
612 indices: None,
613 tesselation: None,
614 });
615 let fc_clone_new_geometry =
616 VectorFeature::<MetaTest>::from_vector_feature(&fc, Some(new_geo.clone()));
617
618 assert_eq!(fc_clone_new_geometry.geometry, new_geo);
619 }
620
621 #[test]
622 fn parse_feature_multipoint() {
623 let json_string = r#"{
624 "type": "Feature",
625 "properties": {},
626 "geometry": {
627 "type": "MultiPoint",
628 "coordinates": [
629 [-13.292352825505162, 54.34883408204476],
630 [36.83102287804303, 59.56941785818924],
631 [50.34083898563978, 16.040052775278994],
632 [76.38149901912357, 35.155968522292056]
633 ]
634 }
635 }"#;
636
637 let feature: Feature = serde_json::from_str(json_string).unwrap();
638 assert_eq!(feature._type, "Feature".into());
639 assert_eq!(
640 feature.geometry,
641 Geometry::MultiPoint(MultiPointGeometry {
642 _type: "MultiPoint".into(),
643 coordinates: vec![
644 Point(-13.292352825505162, 54.34883408204476),
645 Point(36.83102287804303, 59.56941785818924),
646 Point(50.34083898563978, 16.040052775278994),
647 Point(76.38149901912357, 35.155968522292056),
648 ],
649 ..Default::default()
650 })
651 );
652
653 let back_to_str = serde_json::to_string(&feature).unwrap();
654 assert_eq!(
655 back_to_str,
656 "{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"MultiPoint\",\"\
657 coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
658 56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
659 155968522292056]]}}"
660 );
661 }
662
663 #[test]
664 fn parse_feature_linestring() {
665 let json_string = r#"{
666 "type": "Feature",
667 "properties": {},
668 "geometry": {
669 "type": "LineString",
670 "coordinates": [
671 [-13.292352825505162, 54.34883408204476],
672 [36.83102287804303, 59.56941785818924],
673 [50.34083898563978, 16.040052775278994],
674 [76.38149901912357, 35.155968522292056]
675 ]
676 }
677 }"#;
678
679 let feature: Feature = serde_json::from_str(json_string).unwrap();
680 assert_eq!(feature._type, "Feature".into());
681 assert_eq!(
682 feature.geometry,
683 Geometry::LineString(LineStringGeometry {
684 _type: "LineString".into(),
685 coordinates: vec![
686 Point(-13.292352825505162, 54.34883408204476),
687 Point(36.83102287804303, 59.56941785818924),
688 Point(50.34083898563978, 16.040052775278994),
689 Point(76.38149901912357, 35.155968522292056),
690 ],
691 ..Default::default()
692 })
693 );
694
695 let back_to_str = serde_json::to_string(&feature).unwrap();
696 assert_eq!(
697 back_to_str,
698 "{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"\
699 coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
700 56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
701 155968522292056]]}}"
702 );
703 }
704
705 #[test]
706 fn parse_vector_feature_linestring() {
707 let json_string = r#"{
708 "type": "VectorFeature",
709 "face": 0,
710 "properties": {},
711 "geometry": {
712 "type": "LineString",
713 "is3D": false,
714 "coordinates": [
715 { "x": -13.292352825505162, "y": 54.34883408204476 },
716 { "x": 36.83102287804303, "y": 59.56941785818924 },
717 { "x": 50.34083898563978, "y": 16.040052775278994 },
718 { "x": 76.38149901912357, "y": 35.155968522292056 }
719 ]
720 }
721 }"#;
722
723 let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
724 assert_eq!(feature._type, "VectorFeature".into());
725 let geometry = feature.geometry;
726 assert_eq!(
727 geometry,
728 VectorGeometry::LineString(VectorLineStringGeometry {
729 _type: VectorGeometryType::LineString,
730 is_3d: false,
731 coordinates: vec![
732 VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
733 VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
734 VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
735 VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
736 ],
737 ..Default::default()
738 })
739 )
740 }
741
742 #[test]
743 fn parse_vector_feature_multipoint() {
744 let json_string = r#"{
745 "type": "VectorFeature",
746 "face": 0,
747 "properties": {},
748 "geometry": {
749 "type": "MultiPoint",
750 "is3D": false,
751 "coordinates": [
752 { "x": -13.292352825505162, "y": 54.34883408204476 },
753 { "x": 36.83102287804303, "y": 59.56941785818924 },
754 { "x": 50.34083898563978, "y": 16.040052775278994 },
755 { "x": 76.38149901912357, "y": 35.155968522292056 }
756 ]
757 }
758 }"#;
759
760 let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
761 assert_eq!(feature._type, "VectorFeature".into());
762 let geometry = feature.geometry;
763 assert_eq!(
764 geometry,
765 VectorGeometry::MultiPoint(VectorMultiPointGeometry {
766 _type: VectorGeometryType::MultiPoint,
767 is_3d: false,
768 coordinates: vec![
769 VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
770 VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
771 VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
772 VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
773 ],
774 ..Default::default()
775 })
776 )
777 }
778
779 #[test]
780 fn serde_face() {
781 let face_0 = Face::Face0;
782 let serialized = serde_json::to_string(&face_0).unwrap();
783 assert_eq!(serialized, "0");
784 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
785 assert_eq!(deserialize, Face::Face0);
786
787 let face_1 = Face::Face1;
788 let serialized = serde_json::to_string(&face_1).unwrap();
789 assert_eq!(serialized, "1");
790 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
791 assert_eq!(deserialize, Face::Face1);
792
793 let face_2 = Face::Face2;
794 let serialized = serde_json::to_string(&face_2).unwrap();
795 assert_eq!(serialized, "2");
796 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
797 assert_eq!(deserialize, Face::Face2);
798
799 let face_3 = Face::Face3;
800 let serialized = serde_json::to_string(&face_3).unwrap();
801 assert_eq!(serialized, "3");
802 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
803 assert_eq!(deserialize, Face::Face3);
804
805 let face_4 = Face::Face4;
806 let serialized = serde_json::to_string(&face_4).unwrap();
807 assert_eq!(serialized, "4");
808 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
809 assert_eq!(deserialize, Face::Face4);
810
811 let face_5 = Face::Face5;
812 let serialized = serde_json::to_string(&face_5).unwrap();
813 assert_eq!(serialized, "5");
814 let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
815 assert_eq!(deserialize, Face::Face5);
816 }
817
818 #[test]
819 #[should_panic(expected = "Invalid face value")]
820 fn serde_face_err() {
821 let _ = serde_json::from_str::<Face>("6").unwrap();
822 }
823}