@@ -442,7 +442,18 @@ where
442442 if let JsonValue :: Object ( _) = value {
443443 hash_map. insert ( "geometry" . to_string ( ) , value) ;
444444 } else {
445- return Err ( Error :: custom ( "GeoJSON Feature had a unexpected geometry" ) ) ;
445+ return Err ( Error :: custom (
446+ "GeoJSON Feature had an unexpected `geometry`" ,
447+ ) ) ;
448+ }
449+ } else if key == "id" {
450+ match & value {
451+ JsonValue :: String ( _) | JsonValue :: Number ( _) | JsonValue :: Null => {
452+ hash_map. insert ( "id" . to_string ( ) , value) ;
453+ }
454+ _ => {
455+ return Err ( Error :: custom ( "GeoJSON Feature had an unexpected `id`" ) ) ;
456+ }
446457 }
447458 } else if key == "properties" {
448459 if let JsonValue :: Object ( properties) = value {
@@ -451,7 +462,7 @@ where
451462 hash_map. insert ( prop_key, prop_value) ;
452463 }
453464 } else {
454- return Err ( Error :: custom ( "GeoJSON Feature had a unexpected geometry " ) ) ;
465+ return Err ( Error :: custom ( "GeoJSON Feature had unexpected `properties` " ) ) ;
455466 }
456467 } else {
457468 log:: debug!( "foreign members are not handled by Feature deserializer" )
@@ -663,6 +674,141 @@ pub(crate) mod tests {
663674 assert ! ( feature. geometry. is_none( ) )
664675 }
665676
677+ mod id_field {
678+ use super :: * ;
679+
680+ #[ test]
681+ fn string_id ( ) {
682+ #[ derive( Deserialize ) ]
683+ struct MyStruct {
684+ #[ serde( deserialize_with = "deserialize_geometry" ) ]
685+ geometry : geo_types:: Point < f64 > ,
686+ name : String ,
687+ age : u64 ,
688+ id : String ,
689+ }
690+
691+ let feature_string = json ! ( {
692+ "type" : "Feature" ,
693+ "id" : "my-id-123" ,
694+ "geometry" : {
695+ "type" : "Point" ,
696+ "coordinates" : [ 125.6 , 10.1 ]
697+ } ,
698+ "properties" : {
699+ "name" : "Dinagat Islands" ,
700+ "age" : 123
701+ }
702+ } )
703+ . to_string ( ) ;
704+
705+ let my_struct: MyStruct = deserialize_single_feature ( feature_string. as_bytes ( ) )
706+ . expect ( "a valid feature collection" ) ;
707+
708+ assert_eq ! ( my_struct. geometry, geo_types:: point!( x: 125.6 , y: 10.1 ) ) ;
709+ assert_eq ! ( my_struct. id, "my-id-123" ) ;
710+ assert_eq ! ( my_struct. name, "Dinagat Islands" ) ;
711+ assert_eq ! ( my_struct. age, 123 ) ;
712+ }
713+
714+ #[ test]
715+ fn numeric_id ( ) {
716+ #[ derive( Deserialize ) ]
717+ struct MyStruct {
718+ #[ serde( deserialize_with = "deserialize_geometry" ) ]
719+ geometry : geo_types:: Point < f64 > ,
720+ name : String ,
721+ age : u64 ,
722+ id : u64 ,
723+ }
724+
725+ let feature_string = json ! ( {
726+ "type" : "Feature" ,
727+ "id" : 123 ,
728+ "geometry" : {
729+ "type" : "Point" ,
730+ "coordinates" : [ 125.6 , 10.1 ]
731+ } ,
732+ "properties" : {
733+ "name" : "Dinagat Islands" ,
734+ "age" : 222
735+ }
736+ } )
737+ . to_string ( ) ;
738+
739+ let my_struct: MyStruct = deserialize_single_feature ( feature_string. as_bytes ( ) )
740+ . expect ( "a valid feature collection" ) ;
741+
742+ assert_eq ! ( my_struct. geometry, geo_types:: point!( x: 125.6 , y: 10.1 ) ) ;
743+ assert_eq ! ( my_struct. id, 123 ) ;
744+ assert_eq ! ( my_struct. name, "Dinagat Islands" ) ;
745+ assert_eq ! ( my_struct. age, 222 ) ;
746+ }
747+
748+ #[ test]
749+ fn optional_id ( ) {
750+ #[ allow( unused) ]
751+ #[ derive( Deserialize ) ]
752+ struct MyStruct {
753+ #[ serde( deserialize_with = "deserialize_geometry" ) ]
754+ geometry : geo_types:: Point < f64 > ,
755+ name : String ,
756+ age : u64 ,
757+ id : Option < u64 > ,
758+ }
759+
760+ let feature_string = json ! ( {
761+ "type" : "Feature" ,
762+ "id" : 123 ,
763+ "geometry" : {
764+ "type" : "Point" ,
765+ "coordinates" : [ 125.6 , 10.1 ]
766+ } ,
767+ "properties" : {
768+ "name" : "Dinagat Islands" ,
769+ "age" : 222
770+ }
771+ } )
772+ . to_string ( ) ;
773+ let my_struct: MyStruct = deserialize_single_feature ( feature_string. as_bytes ( ) )
774+ . expect ( "a valid feature collection" ) ;
775+ assert_eq ! ( my_struct. id, Some ( 123 ) ) ;
776+
777+ let feature_string = json ! ( {
778+ "type" : "Feature" ,
779+ "geometry" : {
780+ "type" : "Point" ,
781+ "coordinates" : [ 125.6 , 10.1 ]
782+ } ,
783+ "properties" : {
784+ "name" : "Dinagat Islands" ,
785+ "age" : 222
786+ }
787+ } )
788+ . to_string ( ) ;
789+ let my_struct: MyStruct = deserialize_single_feature ( feature_string. as_bytes ( ) )
790+ . expect ( "a valid feature collection" ) ;
791+ assert_eq ! ( my_struct. id, None ) ;
792+
793+ let feature_string = json ! ( {
794+ "type" : "Feature" ,
795+ "id" : null,
796+ "geometry" : {
797+ "type" : "Point" ,
798+ "coordinates" : [ 125.6 , 10.1 ]
799+ } ,
800+ "properties" : {
801+ "name" : "Dinagat Islands" ,
802+ "age" : 222
803+ }
804+ } )
805+ . to_string ( ) ;
806+ let my_struct: MyStruct = deserialize_single_feature ( feature_string. as_bytes ( ) )
807+ . expect ( "a valid feature collection" ) ;
808+ assert_eq ! ( my_struct. id, None ) ;
809+ }
810+ }
811+
666812 #[ test]
667813 fn test_from_feature ( ) {
668814 #[ derive( Debug , PartialEq , Deserialize ) ]
0 commit comments