s2json_core/geometry/
impls.rs

1use crate::*;
2
3// We have to manually implement the Deserialize trait to fix a compilation error
4#[doc(hidden)]
5#[allow(unused_extern_crates, clippy::useless_attribute)]
6extern crate serde as _serde;
7#[automatically_derived]
8// #[coverage(off)]
9impl<'de, M: Clone + Default> Deserialize<'de> for Geometry<M>
10where
11    M: Deserialize<'de>,
12{
13    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
14    where
15        D: _serde::Deserializer<'de>,
16    {
17        // 1. Deserialize into an intermediate Value.
18        let value = serde_json::Value::deserialize(deserializer)?;
19
20        // 2. Attempt to deserialize from the `value` into each possible variant.
21        // We use serde_json::from_value(value.clone()) to create owned instances
22        // and avoid the lifetime error where a borrow outlives the owned 'value'.
23        if let Ok(geom) = PointGeometry::<M>::deserialize(value.clone()) {
24            return Ok(Geometry::Point(geom));
25        }
26
27        // Attempt to deserialize as MultiPoint then check if it's actually a LineString
28        if let Ok(multipoint) = MultiPointGeometry::<M>::deserialize(value.clone()) {
29            if multipoint._type == GeometryType::LineString
30                && let Ok(linestring) = LineStringGeometry::<M>::deserialize(value.clone())
31            {
32                return Ok(Geometry::LineString(linestring));
33            }
34            // Otherwise, or if LineString parsing failed, we fall back to the valid MultiPoint.
35            return Ok(Geometry::MultiPoint(multipoint));
36        }
37
38        // Attempt as MultiLineString, then check for Polygon
39        if let Ok(multilinestring) = MultiLineStringGeometry::<M>::deserialize(value.clone()) {
40            if multilinestring._type == GeometryType::Polygon
41                && let Ok(polygon) = PolygonGeometry::<M>::deserialize(value.clone())
42            {
43                return Ok(Geometry::Polygon(polygon));
44            }
45            return Ok(Geometry::MultiLineString(multilinestring));
46        }
47
48        if let Ok(geom) = MultiPolygonGeometry::<M>::deserialize(value.clone()) {
49            return Ok(Geometry::MultiPolygon(geom));
50        }
51        if let Ok(geom) = Point3DGeometry::<M>::deserialize(value.clone()) {
52            return Ok(Geometry::Point3D(geom));
53        }
54
55        // Attempt as MultiPoint3D, then check for LineString3D
56        if let Ok(multipoint3d) = MultiPoint3DGeometry::<M>::deserialize(value.clone()) {
57            if multipoint3d._type == GeometryType::LineString3D
58                && let Ok(linestring3d) = LineString3DGeometry::<M>::deserialize(value.clone())
59            {
60                return Ok(Geometry::LineString3D(linestring3d));
61            }
62            return Ok(Geometry::MultiPoint3D(multipoint3d));
63        }
64
65        // Attempt as MultiLineString3D, then check for Polygon3D
66        if let Ok(multilinestring3d) = MultiLineString3DGeometry::<M>::deserialize(value.clone()) {
67            if multilinestring3d._type == GeometryType::Polygon3D
68                && let Ok(polygon3d) = Polygon3DGeometry::<M>::deserialize(value.clone())
69            {
70                return Ok(Geometry::Polygon3D(polygon3d));
71            }
72            return Ok(Geometry::MultiLineString3D(multilinestring3d));
73        }
74
75        if let Ok(geom) = MultiPolygon3DGeometry::<M>::deserialize(value.clone()) {
76            return Ok(Geometry::MultiPolygon3D(geom));
77        }
78
79        Err(_serde::de::Error::custom("data did not match any variant of untagged enum Geometry"))
80    }
81}
82
83#[doc(hidden)]
84#[allow(unused_extern_crates, clippy::useless_attribute)]
85#[automatically_derived]
86// #[coverage(off)]
87impl<'de, M: Clone + Default> Deserialize<'de> for VectorGeometry<M>
88where
89    M: Deserialize<'de>,
90{
91    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
92    where
93        D: _serde::Deserializer<'de>,
94    {
95        let value = serde_json::Value::deserialize(deserializer)?;
96
97        if let Ok(geom) = VectorPointGeometry::<M>::deserialize(value.clone()) {
98            return Ok(VectorGeometry::Point(geom));
99        }
100
101        // Attempt to deserialize as MultiPoint, then check for LineString
102        if let Ok(multipoint) = VectorMultiPointGeometry::<M>::deserialize(value.clone()) {
103            if multipoint._type == VectorGeometryType::LineString
104                && let Ok(linestring) = VectorLineStringGeometry::<M>::deserialize(value.clone())
105            {
106                return Ok(VectorGeometry::LineString(linestring));
107            }
108            return Ok(VectorGeometry::MultiPoint(multipoint));
109        }
110
111        // Attempt to deserialize as MultiLineString, then check for Polygon
112        if let Ok(multilinestring) = VectorMultiLineStringGeometry::<M>::deserialize(value.clone())
113        {
114            if multilinestring._type == VectorGeometryType::Polygon
115                && let Ok(polygon) = VectorPolygonGeometry::<M>::deserialize(value.clone())
116            {
117                return Ok(VectorGeometry::Polygon(polygon));
118            }
119            return Ok(VectorGeometry::MultiLineString(multilinestring));
120        }
121
122        if let Ok(geom) = VectorMultiPolygonGeometry::<M>::deserialize(value.clone()) {
123            return Ok(VectorGeometry::MultiPolygon(geom));
124        }
125
126        Err(_serde::de::Error::custom(
127            "data did not match any variant of untagged enum VectorGeometry",
128        ))
129    }
130}