@@ -3,7 +3,7 @@ use std::{collections::HashSet, ops::Deref};
33use graph:: {
44 components:: store:: EntityType ,
55 data:: graphql:: { DocumentExt , ObjectOrInterface } ,
6- prelude:: { anyhow, q, r, s, QueryExecutionError , Schema , ValueMap } ,
6+ prelude:: { anyhow, q, r, s, ApiSchema , QueryExecutionError , ValueMap } ,
77} ;
88use graphql_parser:: Pos ;
99
@@ -23,13 +23,16 @@ use crate::schema::ast::ObjectType;
2323pub struct SelectionSet {
2424 // Map object types to the list of fields that should be selected for
2525 // them
26- items : Vec < ( String , Vec < Field > ) > ,
26+ items : Vec < ( ObjectType , Vec < Field > ) > ,
2727}
2828
2929impl SelectionSet {
3030 /// Create a new `SelectionSet` that can handle the given types
31- pub fn new ( types : Vec < String > ) -> Self {
32- let items = types. into_iter ( ) . map ( |name| ( name, Vec :: new ( ) ) ) . collect ( ) ;
31+ pub fn new ( types : Vec < ObjectType > ) -> Self {
32+ let items = types
33+ . into_iter ( )
34+ . map ( |obj_type| ( obj_type, Vec :: new ( ) ) )
35+ . collect ( ) ;
3336 SelectionSet { items }
3437 }
3538
@@ -76,29 +79,28 @@ impl SelectionSet {
7679 }
7780
7881 /// Iterate over all types and the fields for those types
79- pub fn fields ( & self ) -> impl Iterator < Item = ( & str , impl Iterator < Item = & Field > ) > {
82+ pub fn fields ( & self ) -> impl Iterator < Item = ( & ObjectType , impl Iterator < Item = & Field > ) > {
8083 self . items
8184 . iter ( )
82- . map ( |( name , fields) | ( name . as_str ( ) , fields. iter ( ) ) )
85+ . map ( |( obj_type , fields) | ( obj_type , fields. iter ( ) ) )
8386 }
8487
8588 /// Iterate over all types and the fields that are not leaf fields, i.e.
8689 /// whose selection sets are not empty
87- pub fn interior_fields ( & self ) -> impl Iterator < Item = ( & str , impl Iterator < Item = & Field > ) > {
88- self . items . iter ( ) . map ( |( name, fields) | {
89- (
90- name. as_str ( ) ,
91- fields. iter ( ) . filter ( |field| !field. is_leaf ( ) ) ,
92- )
93- } )
90+ pub fn interior_fields (
91+ & self ,
92+ ) -> impl Iterator < Item = ( & ObjectType , impl Iterator < Item = & Field > ) > {
93+ self . items
94+ . iter ( )
95+ . map ( |( obj_type, fields) | ( obj_type, fields. iter ( ) . filter ( |field| !field. is_leaf ( ) ) ) )
9496 }
9597
9698 /// Iterate over all fields for the given object type
97- pub fn fields_for ( & self , obj_type : & s :: ObjectType ) -> impl Iterator < Item = & Field > {
99+ pub fn fields_for ( & self , obj_type : & ObjectType ) -> impl Iterator < Item = & Field > {
98100 let item = self
99101 . items
100102 . iter ( )
101- . find ( |( name , _) | name == & obj_type. name )
103+ . find ( |( our_type , _) | our_type == obj_type)
102104 . expect ( "there is an entry for the type" ) ;
103105 item. 1 . iter ( )
104106 }
@@ -254,14 +256,14 @@ impl ValueMap for Field {
254256/// object types that implement them, and possibly narrowing further when
255257/// expanding fragments with type conitions
256258#[ derive( Debug , Clone , PartialEq ) ]
257- pub enum ObjectTypeSet {
259+ pub ( crate ) enum ObjectTypeSet {
258260 Any ,
259- Only ( HashSet < String > ) ,
261+ Only ( HashSet < ObjectType > ) ,
260262}
261263
262264impl ObjectTypeSet {
263265 pub fn convert (
264- schema : & Schema ,
266+ schema : & ApiSchema ,
265267 type_cond : Option < & q:: TypeCondition > ,
266268 ) -> Result < ObjectTypeSet , QueryExecutionError > {
267269 match type_cond {
@@ -270,64 +272,60 @@ impl ObjectTypeSet {
270272 }
271273 }
272274
273- pub fn from_name ( schema : & Schema , name : & str ) -> Result < ObjectTypeSet , QueryExecutionError > {
274- let set = resolve_object_types ( schema, name) ?
275- . into_iter ( )
276- . map ( |ty| ty. name ( ) . to_string ( ) )
277- . collect ( ) ;
275+ pub fn from_name ( schema : & ApiSchema , name : & str ) -> Result < ObjectTypeSet , QueryExecutionError > {
276+ let set = resolve_object_types ( schema, name) ?;
278277 Ok ( ObjectTypeSet :: Only ( set) )
279278 }
280279
281- fn matches_name ( & self , name : & str ) -> bool {
280+ fn contains ( & self , obj_type : & ObjectType ) -> bool {
282281 match self {
283282 ObjectTypeSet :: Any => true ,
284- ObjectTypeSet :: Only ( set) => set. contains ( name ) ,
283+ ObjectTypeSet :: Only ( set) => set. contains ( obj_type ) ,
285284 }
286285 }
287286
288287 pub fn intersect ( self , other : & ObjectTypeSet ) -> ObjectTypeSet {
289288 match self {
290289 ObjectTypeSet :: Any => other. clone ( ) ,
291- ObjectTypeSet :: Only ( set) => ObjectTypeSet :: Only (
292- set. into_iter ( )
293- . filter ( |ty| other. matches_name ( ty) )
294- . collect ( ) ,
295- ) ,
290+ ObjectTypeSet :: Only ( set) => {
291+ ObjectTypeSet :: Only ( set. into_iter ( ) . filter ( |ty| other. contains ( ty) ) . collect ( ) )
292+ }
296293 }
297294 }
298295
299296 /// Return a list of the object type names that are in this type set and
300297 /// are also implementations of `current_type`
301298 pub fn type_names (
302299 & self ,
303- schema : & Schema ,
300+ schema : & ApiSchema ,
304301 current_type : ObjectOrInterface < ' _ > ,
305- ) -> Result < Vec < String > , QueryExecutionError > {
302+ ) -> Result < Vec < ObjectType > , QueryExecutionError > {
306303 Ok ( resolve_object_types ( schema, current_type. name ( ) ) ?
307304 . into_iter ( )
308- . map ( |obj| obj. name ( ) . to_string ( ) )
309- . filter ( |name| match self {
305+ . filter ( |obj_type| match self {
310306 ObjectTypeSet :: Any => true ,
311- ObjectTypeSet :: Only ( set) => set. contains ( name . as_str ( ) ) ,
307+ ObjectTypeSet :: Only ( set) => set. contains ( obj_type ) ,
312308 } )
313- . collect :: < Vec < String > > ( ) )
309+ . collect ( ) )
314310 }
315311}
316312
317313/// Look up the type `name` from the schema and resolve interfaces
318314/// and unions until we are left with a set of concrete object types
319- pub ( crate ) fn resolve_object_types < ' a > (
320- schema : & ' a Schema ,
315+ pub ( crate ) fn resolve_object_types (
316+ schema : & ApiSchema ,
321317 name : & str ,
322- ) -> Result < HashSet < ObjectType < ' a > > , QueryExecutionError > {
318+ ) -> Result < HashSet < ObjectType > , QueryExecutionError > {
323319 let mut set = HashSet :: new ( ) ;
324320 match schema
321+ . schema
325322 . document
326323 . get_named_type ( name)
327324 . ok_or_else ( || QueryExecutionError :: AbstractTypeError ( name. to_string ( ) ) ) ?
328325 {
329326 s:: TypeDefinition :: Interface ( intf) => {
330327 for obj_ty in & schema. types_for_interface ( ) [ & EntityType :: new ( intf. name . to_string ( ) ) ] {
328+ let obj_ty = schema. object_type ( obj_ty) ;
331329 set. insert ( obj_ty. into ( ) ) ;
332330 }
333331 }
@@ -337,6 +335,7 @@ pub(crate) fn resolve_object_types<'a>(
337335 }
338336 }
339337 s:: TypeDefinition :: Object ( ty) => {
338+ let ty = schema. object_type ( ty) ;
340339 set. insert ( ty. into ( ) ) ;
341340 }
342341 s:: TypeDefinition :: Scalar ( _)
0 commit comments