1
+ use std:: borrow:: Cow ;
1
2
use std:: collections:: HashMap ;
2
3
use std:: sync:: RwLock ;
3
4
@@ -156,25 +157,34 @@ impl<'a, CtxT> Executor<'a, CtxT> {
156
157
/// Resolve a single arbitrary value, mapping the context to a new type
157
158
pub fn resolve_with_ctx < NewCtxT , T : GraphQLType < Context = NewCtxT > > (
158
159
& self ,
160
+ info : & T :: TypeInfo ,
159
161
value : & T ,
160
162
) -> ExecutionResult
161
163
where
162
164
NewCtxT : FromContext < CtxT > ,
163
165
{
164
166
self . replaced_context ( <NewCtxT as FromContext < CtxT > >:: from ( self . context ) )
165
- . resolve ( value)
167
+ . resolve ( info , value)
166
168
}
167
169
168
170
/// Resolve a single arbitrary value into an `ExecutionResult`
169
- pub fn resolve < T : GraphQLType < Context = CtxT > > ( & self , value : & T ) -> ExecutionResult {
170
- Ok ( value. resolve ( self . current_selection_set , self ) )
171
+ pub fn resolve < T : GraphQLType < Context = CtxT > > (
172
+ & self ,
173
+ info : & T :: TypeInfo ,
174
+ value : & T ,
175
+ ) -> ExecutionResult {
176
+ Ok ( value. resolve ( info, self . current_selection_set , self ) )
171
177
}
172
178
173
179
/// Resolve a single arbitrary value into a return value
174
180
///
175
181
/// If the field fails to resolve, `null` will be returned.
176
- pub fn resolve_into_value < T : GraphQLType < Context = CtxT > > ( & self , value : & T ) -> Value {
177
- match self . resolve ( value) {
182
+ pub fn resolve_into_value < T : GraphQLType < Context = CtxT > > (
183
+ & self ,
184
+ info : & T :: TypeInfo ,
185
+ value : & T ,
186
+ ) -> Value {
187
+ match self . resolve ( info, value) {
178
188
Ok ( v) => v,
179
189
Err ( e) => {
180
190
let position = self . field_path . location ( ) . clone ( ) ;
@@ -383,8 +393,10 @@ where
383
393
} ;
384
394
385
395
value = match op. item . operation_type {
386
- OperationType :: Query => executor. resolve_into_value ( & root_node) ,
387
- OperationType :: Mutation => executor. resolve_into_value ( & root_node. mutation_type ) ,
396
+ OperationType :: Query => executor. resolve_into_value ( & root_node. query_info , & root_node) ,
397
+ OperationType :: Mutation => {
398
+ executor. resolve_into_value ( & root_node. mutation_info , & root_node. mutation_type )
399
+ }
388
400
} ;
389
401
}
390
402
@@ -404,67 +416,71 @@ impl<'r> Registry<'r> {
404
416
///
405
417
/// If the registry hasn't seen a type with this name before, it will
406
418
/// construct its metadata and store it.
407
- pub fn get_type < T > ( & mut self ) -> Type < ' r >
419
+ pub fn get_type < T > ( & mut self , info : & T :: TypeInfo ) -> Type < ' r >
408
420
where
409
421
T : GraphQLType ,
410
422
{
411
- if let Some ( name) = T :: name ( ) {
412
- if !self . types . contains_key ( name) {
413
- self . insert_placeholder ( name, Type :: NonNullNamed ( name) ) ;
414
- let meta = T :: meta ( self ) ;
415
- self . types . insert ( name. to_owned ( ) , meta) ;
423
+ if let Some ( name) = T :: name ( info ) {
424
+ if !self . types . contains_key ( & name. to_string ( ) ) {
425
+ self . insert_placeholder ( & name, Type :: NonNullNamed ( Cow :: Owned ( name. to_string ( ) ) ) ) ;
426
+ let meta = T :: meta ( info , self ) ;
427
+ self . types . insert ( name. to_string ( ) , meta) ;
416
428
}
417
- self . types [ name] . as_type ( )
429
+ self . types [ & name. to_string ( ) ] . as_type ( )
418
430
} else {
419
- T :: meta ( self ) . as_type ( )
431
+ T :: meta ( info , self ) . as_type ( )
420
432
}
421
433
}
422
434
423
435
/// Create a field with the provided name
424
- pub fn field < T > ( & mut self , name : & str ) -> Field < ' r >
436
+ pub fn field < T > ( & mut self , name : & str , info : & T :: TypeInfo ) -> Field < ' r >
425
437
where
426
438
T : GraphQLType ,
427
439
{
428
440
Field {
429
441
name : name. to_owned ( ) ,
430
442
description : None ,
431
443
arguments : None ,
432
- field_type : self . get_type :: < T > ( ) ,
444
+ field_type : self . get_type :: < T > ( info ) ,
433
445
deprecation_reason : None ,
434
446
}
435
447
}
436
448
437
449
#[ doc( hidden) ]
438
- pub fn field_convert < ' a , T : IntoResolvable < ' a , I , C > , I , C > ( & mut self , name : & str ) -> Field < ' r >
450
+ pub fn field_convert < ' a , T : IntoResolvable < ' a , I , C > , I , C > (
451
+ & mut self ,
452
+ name : & str ,
453
+ info : & I :: TypeInfo ,
454
+ ) -> Field < ' r >
439
455
where
440
456
I : GraphQLType ,
441
457
{
442
458
Field {
443
459
name : name. to_owned ( ) ,
444
460
description : None ,
445
461
arguments : None ,
446
- field_type : self . get_type :: < I > ( ) ,
462
+ field_type : self . get_type :: < I > ( info ) ,
447
463
deprecation_reason : None ,
448
464
}
449
465
}
450
466
451
467
/// Create an argument with the provided name
452
- pub fn arg < T > ( & mut self , name : & str ) -> Argument < ' r >
468
+ pub fn arg < T > ( & mut self , name : & str , info : & T :: TypeInfo ) -> Argument < ' r >
453
469
where
454
470
T : GraphQLType + FromInputValue ,
455
471
{
456
- Argument :: new ( name, self . get_type :: < T > ( ) )
472
+ Argument :: new ( name, self . get_type :: < T > ( info ) )
457
473
}
458
474
459
475
/// Create an argument with a default value
460
476
///
461
477
/// When called with type `T`, the actual argument will be given the type
462
478
/// `Option<T>`.
463
- pub fn arg_with_default < T > ( & mut self , name : & str , value : & T ) -> Argument < ' r >
479
+ pub fn arg_with_default < T > ( & mut self , name : & str , value : & T , info : & T :: TypeInfo ) -> Argument < ' r >
464
480
where
465
481
T : GraphQLType + ToInputValue + FromInputValue ,
466
482
{
467
- Argument :: new ( name, self . get_type :: < Option < T > > ( ) ) . default_value ( value. to ( ) )
483
+ Argument :: new ( name, self . get_type :: < Option < T > > ( info ) ) . default_value ( value. to ( ) )
468
484
}
469
485
470
486
fn insert_placeholder ( & mut self , name : & str , of_type : Type < ' r > ) {
@@ -479,80 +495,93 @@ impl<'r> Registry<'r> {
479
495
/// Create a scalar meta type
480
496
///
481
497
/// This expects the type to implement `FromInputValue`.
482
- pub fn build_scalar_type < T > ( & mut self ) -> ScalarMeta < ' r >
498
+ pub fn build_scalar_type < T > ( & mut self , info : & T :: TypeInfo ) -> ScalarMeta < ' r >
483
499
where
484
500
T : FromInputValue + GraphQLType ,
485
501
{
486
- let name = T :: name ( ) . expect ( "Scalar types must be named. Implement name()" ) ;
487
- ScalarMeta :: new :: < T > ( name)
502
+ let name = T :: name ( info ) . expect ( "Scalar types must be named. Implement name()" ) ;
503
+ ScalarMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) )
488
504
}
489
505
490
506
/// Create a list meta type
491
- pub fn build_list_type < T : GraphQLType > ( & mut self ) -> ListMeta < ' r > {
492
- let of_type = self . get_type :: < T > ( ) ;
507
+ pub fn build_list_type < T : GraphQLType > ( & mut self , info : & T :: TypeInfo ) -> ListMeta < ' r > {
508
+ let of_type = self . get_type :: < T > ( info ) ;
493
509
ListMeta :: new ( of_type)
494
510
}
495
511
496
512
/// Create a nullable meta type
497
- pub fn build_nullable_type < T : GraphQLType > ( & mut self ) -> NullableMeta < ' r > {
498
- let of_type = self . get_type :: < T > ( ) ;
513
+ pub fn build_nullable_type < T : GraphQLType > ( & mut self , info : & T :: TypeInfo ) -> NullableMeta < ' r > {
514
+ let of_type = self . get_type :: < T > ( info ) ;
499
515
NullableMeta :: new ( of_type)
500
516
}
501
517
502
518
/// Create an object meta type builder
503
519
///
504
520
/// To prevent infinite recursion by enforcing ordering, this returns a
505
521
/// function that needs to be called with the list of fields on the object.
506
- pub fn build_object_type < T > ( & mut self , fields : & [ Field < ' r > ] ) -> ObjectMeta < ' r >
522
+ pub fn build_object_type < T > (
523
+ & mut self ,
524
+ info : & T :: TypeInfo ,
525
+ fields : & [ Field < ' r > ] ,
526
+ ) -> ObjectMeta < ' r >
507
527
where
508
528
T : GraphQLType ,
509
529
{
510
- let name = T :: name ( ) . expect ( "Object types must be named. Implement name()" ) ;
530
+ let name = T :: name ( info ) . expect ( "Object types must be named. Implement name()" ) ;
511
531
512
532
let mut v = fields. to_vec ( ) ;
513
- v. push ( self . field :: < String > ( "__typename" ) ) ;
514
- ObjectMeta :: new ( name, & v)
533
+ v. push ( self . field :: < String > ( "__typename" , & ( ) ) ) ;
534
+ ObjectMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , & v)
515
535
}
516
536
517
537
/// Create an enum meta type
518
- pub fn build_enum_type < T > ( & mut self , values : & [ EnumValue ] ) -> EnumMeta < ' r >
538
+ pub fn build_enum_type < T > ( & mut self , info : & T :: TypeInfo , values : & [ EnumValue ] ) -> EnumMeta < ' r >
519
539
where
520
540
T : FromInputValue + GraphQLType ,
521
541
{
522
- let name = T :: name ( ) . expect ( "Enum types must be named. Implement name()" ) ;
542
+ let name = T :: name ( info ) . expect ( "Enum types must be named. Implement name()" ) ;
523
543
524
- EnumMeta :: new :: < T > ( name, values)
544
+ EnumMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) , values)
525
545
}
526
546
527
- /// Create an interface meta type builder
528
- pub fn build_interface_type < T > ( & mut self , fields : & [ Field < ' r > ] ) -> InterfaceMeta < ' r >
547
+ /// Create an interface meta type builder,
548
+ /// by providing a type info object.
549
+ pub fn build_interface_type < T > (
550
+ & mut self ,
551
+ info : & T :: TypeInfo ,
552
+ fields : & [ Field < ' r > ] ,
553
+ ) -> InterfaceMeta < ' r >
529
554
where
530
555
T : GraphQLType ,
531
556
{
532
- let name = T :: name ( ) . expect ( "Interface types must be named. Implement name()" ) ;
557
+ let name = T :: name ( info ) . expect ( "Interface types must be named. Implement name()" ) ;
533
558
534
559
let mut v = fields. to_vec ( ) ;
535
- v. push ( self . field :: < String > ( "__typename" ) ) ;
536
- InterfaceMeta :: new ( name, & v)
560
+ v. push ( self . field :: < String > ( "__typename" , & ( ) ) ) ;
561
+ InterfaceMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , & v)
537
562
}
538
563
539
564
/// Create a union meta type builder
540
- pub fn build_union_type < T > ( & mut self , types : & [ Type < ' r > ] ) -> UnionMeta < ' r >
565
+ pub fn build_union_type < T > ( & mut self , info : & T :: TypeInfo , types : & [ Type < ' r > ] ) -> UnionMeta < ' r >
541
566
where
542
567
T : GraphQLType ,
543
568
{
544
- let name = T :: name ( ) . expect ( "Union types must be named. Implement name()" ) ;
569
+ let name = T :: name ( info ) . expect ( "Union types must be named. Implement name()" ) ;
545
570
546
- UnionMeta :: new ( name, types)
571
+ UnionMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , types)
547
572
}
548
573
549
574
/// Create an input object meta type builder
550
- pub fn build_input_object_type < T > ( & mut self , args : & [ Argument < ' r > ] ) -> InputObjectMeta < ' r >
575
+ pub fn build_input_object_type < T > (
576
+ & mut self ,
577
+ info : & T :: TypeInfo ,
578
+ args : & [ Argument < ' r > ] ,
579
+ ) -> InputObjectMeta < ' r >
551
580
where
552
581
T : FromInputValue + GraphQLType ,
553
582
{
554
- let name = T :: name ( ) . expect ( "Input object types must be named. Implement name()" ) ;
583
+ let name = T :: name ( info ) . expect ( "Input object types must be named. Implement name()" ) ;
555
584
556
- InputObjectMeta :: new :: < T > ( name, args)
585
+ InputObjectMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) , args)
557
586
}
558
587
}
0 commit comments