Skip to content

Commit 22b7f08

Browse files
committed
Permit geometry field on feature objects to be null.
Fixes georust#42.
1 parent a077ac9 commit 22b7f08

File tree

6 files changed

+53
-10
lines changed

6 files changed

+53
-10
lines changed

CHANGES.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changes
2+
3+
## 0.3.0
4+
5+
* [Permit `geometry` field on `feature` objects to be `null`](https://github.com/georust/rust-geojson/issues/42)

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
name = "geojson"
44
description = "Library for serializing the GeoJSON vector GIS file format"
5-
version = "0.2.1"
5+
version = "0.3.0"
66
authors = ["Corey Farwell <coreyf@rwell.org>",
77
"Blake Grotewold <hello@grotewold.me>"]
88
license = "MIT/Apache-2.0"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ properties.insert(
5151
let geojson = GeoJson::Feature(Feature {
5252
crs: None,
5353
bbox: None,
54-
geometry: geometry,
54+
geometry: Some(geometry),
5555
id: None,
5656
properties: Some(properties),
5757
});

src/feature.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ::{Bbox, Crs, Error, FromObject, Geometry, util};
3131
pub struct Feature {
3232
pub bbox: Option<Bbox>,
3333
pub crs: Option<Crs>,
34-
pub geometry: Geometry,
34+
pub geometry: Option<Geometry>,
3535
pub id: Option<JsonValue>,
3636
pub properties: Option<JsonObject>,
3737
}
@@ -105,7 +105,7 @@ impl Deserialize for Feature {
105105

106106
#[cfg(test)]
107107
mod tests {
108-
use ::{Feature, Geometry, Value, GeoJson};
108+
use ::{Error, Feature, Geometry, Value, GeoJson};
109109

110110
fn feature_json_str() -> &'static str {
111111
"{\"geometry\":{\"coordinates\":[1.1,2.1],\"type\":\"Point\"},\"properties\":{},\"type\":\"Feature\"}"
@@ -124,11 +124,11 @@ mod tests {
124124

125125
fn feature() -> Feature {
126126
::Feature {
127-
geometry: Geometry {
127+
geometry: Some(Geometry {
128128
value: Value::Point(vec![1.1, 2.1]),
129129
crs: None,
130130
bbox: None,
131-
},
131+
}),
132132
properties: properties(),
133133
crs: None,
134134
bbox: None,
@@ -173,4 +173,28 @@ mod tests {
173173
};
174174
assert_eq!(decoded_feature, feature);
175175
}
176+
177+
#[test]
178+
fn feature_json_null_geometry() {
179+
let geojson_str = r#"{
180+
"geometry": null,
181+
"properties":{},
182+
"type":"Feature"
183+
}"#;
184+
let geojson = geojson_str.parse::<GeoJson>().unwrap();
185+
let feature = match geojson {
186+
GeoJson::Feature(feature) => feature,
187+
_ => unimplemented!(),
188+
};
189+
assert!(feature.geometry.is_none());
190+
}
191+
192+
#[test]
193+
fn feature_json_invalid_geometry() {
194+
let geojson_str = r#"{"geometry":3.14,"properties":{},"type":"Feature"}"#;
195+
match geojson_str.parse::<GeoJson>().unwrap_err() {
196+
Error::FeatureInvalidGeometryValue => (),
197+
_ => unreachable!(),
198+
}
199+
}
176200
}

src/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
//! let geojson = GeoJson::Feature(Feature {
109109
//! crs: None,
110110
//! bbox: None,
111-
//! geometry: geometry,
111+
//! geometry: Some(geometry),
112112
//! id: None,
113113
//! properties: Some(properties),
114114
//! });
@@ -171,6 +171,7 @@ pub enum Error {
171171
GeometryUnknownType,
172172
MalformedJson,
173173
PropertiesExpectedObjectOrNull,
174+
FeatureInvalidGeometryValue,
174175

175176
// FIXME: make these types more specific
176177
ExpectedStringValue,
@@ -209,6 +210,10 @@ impl std::fmt::Display for Error {
209210
// FIXME: inform what type we actually found
210211
write!(f, "Encountered neither object type nor null type for \
211212
'properties' object."),
213+
Error::FeatureInvalidGeometryValue =>
214+
// FIXME: inform what type we actually found
215+
write!(f, "Encountered neither object type nor null type for \
216+
'geometry' field on 'feature' object."),
212217
Error::ExpectedStringValue =>
213218
write!(f, "Expected a string value."),
214219
Error::ExpectedProperty =>
@@ -236,6 +241,8 @@ impl std::error::Error for Error {
236241
Error::MalformedJson => "malformed JSON",
237242
Error::PropertiesExpectedObjectOrNull =>
238243
"neither object type nor null type for properties' object.",
244+
Error::FeatureInvalidGeometryValue =>
245+
"neither object type nor null type for 'geometry' field on 'feature' object.",
239246
Error::ExpectedStringValue => "expected a string value",
240247
Error::ExpectedProperty => "expected a GeoJSON 'property'",
241248
Error::ExpectedF64Value => "expected a floating-point value",

src/util.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,16 @@ pub fn get_id(object: &JsonObject) -> Result<Option<JsonValue>, Error> {
120120
}
121121

122122
/// Used by Feature
123-
pub fn get_geometry(object: &JsonObject) -> Result<Geometry, Error> {
124-
let geometry = expect_object!(expect_property!(object, "geometry", "Missing 'geometry' field"));
125-
return Geometry::from_object(geometry);
123+
pub fn get_geometry(object: &JsonObject) -> Result<Option<Geometry>, Error> {
124+
let geometry = expect_property!(object, "geometry", "Missing 'geometry' field");
125+
match *geometry {
126+
JsonValue::Object(ref x) => {
127+
let geometry_object = try!(Geometry::from_object(x));
128+
Ok(Some(geometry_object))
129+
},
130+
JsonValue::Null => Ok(None),
131+
_ => Err(Error::FeatureInvalidGeometryValue),
132+
}
126133
}
127134

128135
/// Used by FeatureCollection

0 commit comments

Comments
 (0)