1use crate::errors::{Error, Result};
16use crate::{feature, Bbox, Feature, Geometry, Position, Value};
17use crate::{JsonObject, JsonValue};
18
19pub fn expect_type(value: &mut JsonObject) -> Result<String> {
20 let prop = expect_property(value, "type")?;
21 expect_string(prop)
22}
23
24pub fn expect_string(value: JsonValue) -> Result<String> {
25 match value {
26 JsonValue::String(s) => Ok(s),
27 _ => Err(Error::ExpectedStringValue(value)),
28 }
29}
30
31pub fn expect_f64(value: &JsonValue) -> Result<f64> {
32 match value.as_f64() {
33 Some(v) => Ok(v),
34 None => Err(Error::ExpectedF64Value),
35 }
36}
37
38pub fn expect_array(value: &JsonValue) -> Result<&Vec<JsonValue>> {
39 match value.as_array() {
40 Some(v) => Ok(v),
41 None => Err(Error::ExpectedArrayValue("None".to_string())),
42 }
43}
44
45fn expect_property(obj: &mut JsonObject, name: &'static str) -> Result<JsonValue> {
46 match obj.remove(name) {
47 Some(v) => Ok(v),
48 None => Err(Error::ExpectedProperty(name.to_string())),
49 }
50}
51
52fn expect_owned_array(value: JsonValue) -> Result<Vec<JsonValue>> {
53 match value {
54 JsonValue::Array(v) => Ok(v),
55 _ => match value {
56 JsonValue::Array(_) => Err(Error::ExpectedArrayValue("Array".to_string())),
58 JsonValue::Null => Err(Error::ExpectedArrayValue("Null".to_string())),
59 JsonValue::Bool(_) => Err(Error::ExpectedArrayValue("Bool".to_string())),
60 JsonValue::Number(_) => Err(Error::ExpectedArrayValue("Number".to_string())),
61 JsonValue::String(_) => Err(Error::ExpectedArrayValue("String".to_string())),
62 JsonValue::Object(_) => Err(Error::ExpectedArrayValue("Object".to_string())),
63 },
64 }
65}
66
67pub(crate) fn expect_owned_object(value: JsonValue) -> Result<JsonObject> {
68 match value {
69 JsonValue::Object(o) => Ok(o),
70 _ => Err(Error::ExpectedObjectValue(value)),
71 }
72}
73
74pub fn get_coords_value(object: &mut JsonObject) -> Result<JsonValue> {
75 expect_property(object, "coordinates")
76}
77
78pub fn get_bbox(object: &mut JsonObject) -> Result<Option<Bbox>> {
80 let bbox_json = match object.remove("bbox") {
81 Some(JsonValue::Null) | None => return Ok(None),
82 Some(b) => b,
83 };
84 let bbox_array = match bbox_json {
85 JsonValue::Array(a) => a,
86 _ => return Err(Error::BboxExpectedArray(bbox_json)),
87 };
88 let bbox = bbox_array
89 .into_iter()
90 .map(|i| i.as_f64().ok_or(Error::BboxExpectedNumericValues(i)))
91 .collect::<Result<Vec<_>>>()?;
92 Ok(Some(bbox))
93}
94
95pub fn get_foreign_members(object: JsonObject) -> Result<Option<JsonObject>> {
97 if object.is_empty() {
98 Ok(None)
99 } else {
100 Ok(Some(object))
101 }
102}
103
104pub fn get_properties(object: &mut JsonObject) -> Result<Option<JsonObject>> {
106 let properties = expect_property(object, "properties");
107 match properties {
108 Ok(JsonValue::Object(x)) => Ok(Some(x)),
109 Ok(JsonValue::Null) | Err(Error::ExpectedProperty(_)) => Ok(None),
110 Ok(not_a_dictionary) => Err(Error::PropertiesExpectedObjectOrNull(not_a_dictionary)),
111 Err(e) => Err(e),
112 }
113}
114
115pub fn get_coords_one_pos(object: &mut JsonObject) -> Result<Position> {
119 let coords_json = get_coords_value(object)?;
120 json_to_position(&coords_json)
121}
122
123pub fn get_coords_1d_pos(object: &mut JsonObject) -> Result<Vec<Position>> {
127 let coords_json = get_coords_value(object)?;
128 json_to_1d_positions(&coords_json)
129}
130
131pub fn get_coords_2d_pos(object: &mut JsonObject) -> Result<Vec<Vec<Position>>> {
135 let coords_json = get_coords_value(object)?;
136 json_to_2d_positions(&coords_json)
137}
138
139pub fn get_coords_3d_pos(object: &mut JsonObject) -> Result<Vec<Vec<Vec<Position>>>> {
143 let coords_json = get_coords_value(object)?;
144 json_to_3d_positions(&coords_json)
145}
146
147pub fn get_geometries(object: &mut JsonObject) -> Result<Vec<Geometry>> {
149 let geometries_json = expect_property(object, "geometries")?;
150 let geometries_array = expect_owned_array(geometries_json)?;
151 let mut geometries = Vec::with_capacity(geometries_array.len());
152 for json in geometries_array {
153 let obj = expect_owned_object(json)?;
154 let geometry = Geometry::from_json_object(obj)?;
155 geometries.push(geometry);
156 }
157 Ok(geometries)
158}
159
160pub fn get_id(object: &mut JsonObject) -> Result<Option<feature::Id>> {
162 match object.remove("id") {
163 Some(JsonValue::Number(x)) => Ok(Some(feature::Id::Number(x))),
164 Some(JsonValue::String(s)) => Ok(Some(feature::Id::String(s))),
165 Some(v) => Err(Error::FeatureInvalidIdentifierType(v)),
166 None => Ok(None),
167 }
168}
169
170pub fn get_value(object: &mut JsonObject) -> Result<Value> {
172 let res = &*expect_type(object)?;
173 match res {
174 "Point" => Ok(Value::Point(get_coords_one_pos(object)?)),
175 "MultiPoint" => Ok(Value::MultiPoint(get_coords_1d_pos(object)?)),
176 "LineString" => Ok(Value::LineString(get_coords_1d_pos(object)?)),
177 "MultiLineString" => Ok(Value::MultiLineString(get_coords_2d_pos(object)?)),
178 "Polygon" => Ok(Value::Polygon(get_coords_2d_pos(object)?)),
179 "MultiPolygon" => Ok(Value::MultiPolygon(get_coords_3d_pos(object)?)),
180 "GeometryCollection" => Ok(Value::GeometryCollection(get_geometries(object)?)),
181 _ => Err(Error::GeometryUnknownType(res.to_string())),
182 }
183}
184
185pub fn get_geometry(object: &mut JsonObject) -> Result<Option<Geometry>> {
187 let geometry = expect_property(object, "geometry")?;
188 match geometry {
189 JsonValue::Object(x) => {
190 let geometry_object = Geometry::from_json_object(x)?;
191 Ok(Some(geometry_object))
192 }
193 JsonValue::Null => Ok(None),
194 _ => Err(Error::FeatureInvalidGeometryValue(geometry)),
195 }
196}
197
198pub fn get_features(object: &mut JsonObject) -> Result<Vec<Feature>> {
200 let prop = expect_property(object, "features")?;
201 let features_json = expect_owned_array(prop)?;
202 let mut features = Vec::with_capacity(features_json.len());
203 for feature in features_json {
204 let feature = expect_owned_object(feature)?;
205 let feature: Feature = Feature::from_json_object(feature)?;
206 features.push(feature);
207 }
208 Ok(features)
209}
210
211fn json_to_position(json: &JsonValue) -> Result<Position> {
212 let coords_array = expect_array(json)?;
213 if coords_array.len() < 2 {
214 return Err(Error::PositionTooShort(coords_array.len()));
215 }
216 let mut coords = Vec::with_capacity(coords_array.len());
217 for position in coords_array {
218 coords.push(expect_f64(position)?);
219 }
220 Ok(coords)
221}
222
223fn json_to_1d_positions(json: &JsonValue) -> Result<Vec<Position>> {
224 let coords_array = expect_array(json)?;
225 let mut coords = Vec::with_capacity(coords_array.len());
226 for item in coords_array {
227 coords.push(json_to_position(item)?);
228 }
229 Ok(coords)
230}
231
232fn json_to_2d_positions(json: &JsonValue) -> Result<Vec<Vec<Position>>> {
233 let coords_array = expect_array(json)?;
234 let mut coords = Vec::with_capacity(coords_array.len());
235 for item in coords_array {
236 coords.push(json_to_1d_positions(item)?);
237 }
238 Ok(coords)
239}
240
241fn json_to_3d_positions(json: &JsonValue) -> Result<Vec<Vec<Vec<Position>>>> {
242 let coords_array = expect_array(json)?;
243 let mut coords = Vec::with_capacity(coords_array.len());
244 for item in coords_array {
245 coords.push(json_to_2d_positions(item)?);
246 }
247 Ok(coords)
248}