@@ -740,16 +740,17 @@ lazy_static! {
740740}
741741
742742/// An entity is represented as a map of attribute names to values.
743- #[ derive( Clone , CacheWeight , PartialEq , Eq , Serialize ) ]
743+ #[ derive( Clone , CacheWeight , Eq , Serialize ) ]
744744pub struct Entity ( Object < Value > ) ;
745745
746746impl < ' a > IntoIterator for & ' a Entity {
747- type Item = ( Word , Value ) ;
747+ type Item = ( & ' a str , & ' a Value ) ;
748748
749- type IntoIter = intern:: ObjectOwningIter < Value > ;
749+ type IntoIter =
750+ std:: iter:: Filter < intern:: ObjectIter < ' a , Value > , fn ( & ( & ' a str , & ' a Value ) ) -> bool > ;
750751
751752 fn into_iter ( self ) -> Self :: IntoIter {
752- self . 0 . clone ( ) . into_iter ( )
753+ ( & self . 0 ) . into_iter ( ) . filter ( | ( k , _ ) | * k != VID_FIELD )
753754 }
754755}
755756
@@ -874,10 +875,18 @@ impl Entity {
874875 }
875876
876877 pub fn get ( & self , key : & str ) -> Option < & Value > {
878+ // VID field is private and not visible outside
879+ if key == VID_FIELD {
880+ return None ;
881+ }
877882 self . 0 . get ( key)
878883 }
879884
880885 pub fn contains_key ( & self , key : & str ) -> bool {
886+ // VID field is private and not visible outside
887+ if key == VID_FIELD {
888+ return false ;
889+ }
881890 self . 0 . contains_key ( key)
882891 }
883892
@@ -919,7 +928,8 @@ impl Entity {
919928 /// Return the VID of this entity and if its missing or of a type different than
920929 /// i64 it panics.
921930 pub fn vid ( & self ) -> i64 {
922- self . get ( VID_FIELD )
931+ self . 0
932+ . get ( VID_FIELD )
923933 . expect ( "the vid must be set" )
924934 . as_int8 ( )
925935 . expect ( "the vid must be set to a valid value" )
@@ -930,15 +940,6 @@ impl Entity {
930940 self . 0 . insert ( VID_FIELD , value. into ( ) )
931941 }
932942
933- /// Sets the VID if it's not already set. Should be used only for tests.
934- #[ cfg( debug_assertions) ]
935- pub fn set_vid_if_empty ( & mut self ) {
936- let vid = self . get ( VID_FIELD ) ;
937- if vid. is_none ( ) {
938- let _ = self . set_vid ( 100 ) . expect ( "the vid should be set" ) ;
939- }
940- }
941-
942943 /// Merges an entity update `update` into this entity.
943944 ///
944945 /// If a key exists in both entities, the value from `update` is chosen.
@@ -1062,6 +1063,13 @@ impl Entity {
10621063 }
10631064}
10641065
1066+ /// Checks equality of two entities while ignoring the VID fields
1067+ impl PartialEq for Entity {
1068+ fn eq ( & self , other : & Self ) -> bool {
1069+ self . 0 . eq_ignore_key ( & other. 0 , VID_FIELD )
1070+ }
1071+ }
1072+
10651073/// Convenience methods to modify individual attributes for tests.
10661074/// Production code should not use/need this.
10671075#[ cfg( debug_assertions) ]
@@ -1081,6 +1089,14 @@ impl Entity {
10811089 ) -> Result < Option < Value > , InternError > {
10821090 self . 0 . insert ( name, value. into ( ) )
10831091 }
1092+
1093+ /// Sets the VID if it's not already set. Should be used only for tests.
1094+ pub fn set_vid_if_empty ( & mut self ) {
1095+ let vid = self . 0 . get ( VID_FIELD ) ;
1096+ if vid. is_none ( ) {
1097+ let _ = self . set_vid ( 100 ) . expect ( "the vid should be set" ) ;
1098+ }
1099+ }
10841100}
10851101
10861102impl < ' a > From < & ' a Entity > for Cow < ' a , Entity > {
@@ -1272,3 +1288,47 @@ fn fmt_debug() {
12721288 let bi = Value :: BigInt ( scalar:: BigInt :: from ( -17i32 ) ) ;
12731289 assert_eq ! ( "BigInt(-17)" , format!( "{:?}" , bi) ) ;
12741290}
1291+
1292+ #[ test]
1293+ fn entity_hidden_vid ( ) {
1294+ use crate :: schema:: InputSchema ;
1295+ let subgraph_id = "oneInterfaceOneEntity" ;
1296+ let document = "type Thing @entity {id: ID!, name: String!}" ;
1297+ let schema = InputSchema :: raw ( document, subgraph_id) ;
1298+
1299+ let entity = entity ! { schema => id: "1" , name: "test" , vid: 3i64 } ;
1300+ let debug_str = format ! ( "{:?}" , entity) ;
1301+ let entity_str = "Entity { id: String(\" 1\" ), name: String(\" test\" ), vid: Int8(3) }" ;
1302+ assert_eq ! ( debug_str, entity_str) ;
1303+
1304+ // get returns nothing...
1305+ assert_eq ! ( entity. get( VID_FIELD ) , None ) ;
1306+ assert_eq ! ( entity. contains_key( VID_FIELD ) , false ) ;
1307+ // ...while vid is present
1308+ assert_eq ! ( entity. vid( ) , 3i64 ) ;
1309+
1310+ // into_iter() misses it too
1311+ let mut it = entity. into_iter ( ) ;
1312+ assert_eq ! ( Some ( ( "id" , & Value :: String ( "1" . to_string( ) ) ) ) , it. next( ) ) ;
1313+ assert_eq ! (
1314+ Some ( ( "name" , & Value :: String ( "test" . to_string( ) ) ) ) ,
1315+ it. next( )
1316+ ) ;
1317+ assert_eq ! ( None , it. next( ) ) ;
1318+
1319+ let mut entity2 = entity ! { schema => id: "1" , name: "test" , vid: 5i64 } ;
1320+ assert_eq ! ( entity2. vid( ) , 5i64 ) ;
1321+ // equal with different vid
1322+ assert_eq ! ( entity, entity2) ;
1323+
1324+ entity2. remove ( VID_FIELD ) ;
1325+ // equal if one has no vid
1326+ assert_eq ! ( entity, entity2) ;
1327+ let debug_str2 = format ! ( "{:?}" , entity2) ;
1328+ let entity_str2 = "Entity { id: String(\" 1\" ), name: String(\" test\" ) }" ;
1329+ assert_eq ! ( debug_str2, entity_str2) ;
1330+
1331+ // set again
1332+ _ = entity2. set_vid ( 7i64 ) ;
1333+ assert_eq ! ( entity2. vid( ) , 7i64 ) ;
1334+ }
0 commit comments