1
+ use std:: borrow:: Cow ;
1
2
use std:: collections:: HashMap ;
2
3
use std:: sync:: RwLock ;
3
4
@@ -144,24 +145,24 @@ impl<T> FromContext<T> for T where T: Context {
144
145
impl < ' a , CtxT > Executor < ' a , CtxT > {
145
146
/// Resolve a single arbitrary value, mapping the context to a new type
146
147
pub fn resolve_with_ctx < NewCtxT , T : GraphQLType < Context =NewCtxT > > (
147
- & self , value : & T
148
+ & self , info : & T :: TypeInfo , value : & T
148
149
) -> ExecutionResult
149
150
where NewCtxT : FromContext < CtxT > ,
150
151
{
151
152
self . replaced_context ( <NewCtxT as FromContext < CtxT > >:: from ( self . context ) )
152
- . resolve ( value)
153
+ . resolve ( info , value)
153
154
}
154
155
155
156
/// Resolve a single arbitrary value into an `ExecutionResult`
156
- pub fn resolve < T : GraphQLType < Context =CtxT > > ( & self , value : & T ) -> ExecutionResult {
157
- Ok ( value. resolve ( self . current_selection_set , self ) )
157
+ pub fn resolve < T : GraphQLType < Context =CtxT > > ( & self , info : & T :: TypeInfo , value : & T ) -> ExecutionResult {
158
+ Ok ( value. resolve ( info , self . current_selection_set , self ) )
158
159
}
159
160
160
161
/// Resolve a single arbitrary value into a return value
161
162
///
162
163
/// If the field fails to resolve, `null` will be returned.
163
- pub fn resolve_into_value < T : GraphQLType < Context =CtxT > > ( & self , value : & T ) -> Value {
164
- match self . resolve ( value) {
164
+ pub fn resolve_into_value < T : GraphQLType < Context =CtxT > > ( & self , info : & T :: TypeInfo , value : & T ) -> Value {
165
+ match self . resolve ( info , value) {
165
166
Ok ( v) => v,
166
167
Err ( e) => {
167
168
let position = self . field_path . location ( ) . clone ( ) ;
@@ -364,8 +365,8 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
364
365
} ;
365
366
366
367
value = match op. item . operation_type {
367
- OperationType :: Query => executor. resolve_into_value ( & root_node) ,
368
- OperationType :: Mutation => executor. resolve_into_value ( & root_node. mutation_type ) ,
368
+ OperationType :: Query => executor. resolve_into_value ( & root_node. query_info , & root_node ) ,
369
+ OperationType :: Mutation => executor. resolve_into_value ( & root_node. mutation_info , & root_node . mutation_type ) ,
369
370
} ;
370
371
}
371
372
@@ -387,62 +388,107 @@ impl<'r> Registry<'r> {
387
388
///
388
389
/// If the registry hasn't seen a type with this name before, it will
389
390
/// construct its metadata and store it.
390
- pub fn get_type < T > ( & mut self ) -> Type < ' r > where T : GraphQLType {
391
- if let Some ( name) = T :: name ( ) {
392
- if !self . types . contains_key ( name) {
393
- self . insert_placeholder ( name, Type :: NonNullNamed ( name) ) ;
394
- let meta = T :: meta ( self ) ;
395
- self . types . insert ( name. to_owned ( ) , meta) ;
391
+ pub fn get_type < T > ( & mut self ) -> Type < ' r > where T : GraphQLType < TypeInfo =( ) > {
392
+ self . get_type_with_info :: < T > ( & ( ) )
393
+ }
394
+
395
+ /// Get the `Type` instance for a given GraphQL type,
396
+ /// by providing a type info object.
397
+ ///
398
+ /// If the registry hasn't seen a type with this name before, it will
399
+ /// construct its metadata and store it.
400
+ pub fn get_type_with_info < T > ( & mut self , info : & T :: TypeInfo ) -> Type < ' r > where T : GraphQLType {
401
+ if let Some ( name) = T :: name ( info) {
402
+ if !self . types . contains_key ( & name. to_string ( ) ) {
403
+ self . insert_placeholder ( & name, Type :: NonNullNamed ( Cow :: Owned ( name. to_string ( ) ) ) ) ;
404
+ let meta = T :: meta ( info, self ) ;
405
+ self . types . insert ( name. to_string ( ) , meta) ;
396
406
}
397
- self . types [ name] . as_type ( )
407
+ self . types [ & name. to_string ( ) ] . as_type ( )
398
408
}
399
409
else {
400
- T :: meta ( self ) . as_type ( )
410
+ T :: meta ( info , self ) . as_type ( )
401
411
}
402
412
}
403
413
404
414
/// Create a field with the provided name
405
- pub fn field < T > ( & mut self , name : & str ) -> Field < ' r > where T : GraphQLType {
415
+ pub fn field < T > ( & mut self , name : & str ) -> Field < ' r > where T : GraphQLType < TypeInfo =( ) > {
416
+ self . field_with_info :: < T > ( name, & ( ) )
417
+ }
418
+
419
+ /// Create a field with the provided name,
420
+ /// by providing a type info object.
421
+ pub fn field_with_info < T > ( & mut self , name : & str , info : & T :: TypeInfo ) -> Field < ' r > where T : GraphQLType {
406
422
Field {
407
423
name : name. to_owned ( ) ,
408
424
description : None ,
409
425
arguments : None ,
410
- field_type : self . get_type :: < T > ( ) ,
426
+ field_type : self . get_type_with_info :: < T > ( info ) ,
411
427
deprecation_reason : None ,
412
428
}
413
429
}
414
430
415
431
#[ doc( hidden) ]
416
432
pub fn field_convert < ' a , T : IntoResolvable < ' a , I , C > , I , C > ( & mut self , name : & str ) -> Field < ' r >
433
+ where I : GraphQLType < TypeInfo =( ) >
434
+ {
435
+ self . field_convert_with_info :: < ' a , T , I , C > ( name, & ( ) )
436
+ }
437
+
438
+ #[ doc( hidden) ]
439
+ pub fn field_convert_with_info < ' a , T : IntoResolvable < ' a , I , C > , I , C > ( & mut self , name : & str , info : & I :: TypeInfo ) -> Field < ' r >
417
440
where I : GraphQLType
418
441
{
419
442
Field {
420
443
name : name. to_owned ( ) ,
421
444
description : None ,
422
445
arguments : None ,
423
- field_type : self . get_type :: < I > ( ) ,
446
+ field_type : self . get_type_with_info :: < I > ( info ) ,
424
447
deprecation_reason : None ,
425
448
}
426
449
}
427
450
428
451
/// Create an argument with the provided name
429
- pub fn arg < T > ( & mut self , name : & str ) -> Argument < ' r > where T : GraphQLType + FromInputValue {
430
- Argument :: new ( name, self . get_type :: < T > ( ) )
452
+ pub fn arg < T > ( & mut self , name : & str ) -> Argument < ' r > where T : GraphQLType < TypeInfo =( ) > + FromInputValue {
453
+ self . arg_with_info :: < T > ( name, & ( ) )
454
+ }
455
+
456
+ /// Create an argument with the provided name,
457
+ /// by providing a type info object.
458
+ pub fn arg_with_info < T > ( & mut self , name : & str , info : & T :: TypeInfo ) -> Argument < ' r > where T : GraphQLType + FromInputValue {
459
+ Argument :: new ( name, self . get_type_with_info :: < T > ( info) )
431
460
}
432
461
433
462
/// Create an argument with a default value
434
463
///
435
464
/// When called with type `T`, the actual argument will be given the type
436
465
/// `Option<T>`.
437
466
pub fn arg_with_default < T > (
467
+ & mut self ,
468
+ name : & str ,
469
+ value : & T
470
+ )
471
+ -> Argument < ' r >
472
+ where T : GraphQLType < TypeInfo =( ) > + ToInputValue + FromInputValue
473
+ {
474
+ self . arg_with_default_with_info ( name, value, & ( ) )
475
+ }
476
+
477
+ /// Create an argument with a default value,
478
+ /// by providing a type info object.
479
+ ///
480
+ /// When called with type `T`, the actual argument will be given the type
481
+ /// `Option<T>`.
482
+ pub fn arg_with_default_with_info < T > (
438
483
& mut self ,
439
484
name : & str ,
440
485
value : & T ,
486
+ info : & T :: TypeInfo
441
487
)
442
488
-> Argument < ' r >
443
489
where T : GraphQLType + ToInputValue + FromInputValue
444
490
{
445
- Argument :: new ( name, self . get_type :: < Option < T > > ( ) )
491
+ Argument :: new ( name, self . get_type_with_info :: < Option < T > > ( info ) )
446
492
. default_value ( value. to ( ) )
447
493
}
448
494
@@ -457,22 +503,22 @@ impl<'r> Registry<'r> {
457
503
/// Create a scalar meta type
458
504
///
459
505
/// This expects the type to implement `FromInputValue`.
460
- pub fn build_scalar_type < T > ( & mut self ) -> ScalarMeta < ' r >
506
+ pub fn build_scalar_type < T > ( & mut self , info : & T :: TypeInfo ) -> ScalarMeta < ' r >
461
507
where T : FromInputValue + GraphQLType
462
508
{
463
- let name = T :: name ( ) . expect ( "Scalar types must be named. Implement name()" ) ;
464
- ScalarMeta :: new :: < T > ( name)
509
+ let name = T :: name ( info ) . expect ( "Scalar types must be named. Implement name()" ) ;
510
+ ScalarMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) )
465
511
}
466
512
467
513
/// Create a list meta type
468
- pub fn build_list_type < T : GraphQLType > ( & mut self ) -> ListMeta < ' r > {
469
- let of_type = self . get_type :: < T > ( ) ;
514
+ pub fn build_list_type < T : GraphQLType > ( & mut self , info : & T :: TypeInfo ) -> ListMeta < ' r > {
515
+ let of_type = self . get_type_with_info :: < T > ( info ) ;
470
516
ListMeta :: new ( of_type)
471
517
}
472
518
473
519
/// Create a nullable meta type
474
- pub fn build_nullable_type < T : GraphQLType > ( & mut self ) -> NullableMeta < ' r > {
475
- let of_type = self . get_type :: < T > ( ) ;
520
+ pub fn build_nullable_type < T : GraphQLType > ( & mut self , info : & T :: TypeInfo ) -> NullableMeta < ' r > {
521
+ let of_type = self . get_type_with_info :: < T > ( info ) ;
476
522
NullableMeta :: new ( of_type)
477
523
}
478
524
@@ -481,50 +527,93 @@ impl<'r> Registry<'r> {
481
527
/// To prevent infinite recursion by enforcing ordering, this returns a
482
528
/// function that needs to be called with the list of fields on the object.
483
529
pub fn build_object_type < T > ( & mut self , fields : & [ Field < ' r > ] ) -> ObjectMeta < ' r >
530
+ where T : GraphQLType < TypeInfo =( ) >
531
+ {
532
+ self . build_object_type_with_info :: < T > ( & ( ) , fields)
533
+ }
534
+
535
+ /// Create an object meta type builder,
536
+ /// by providing a type info object.
537
+ ///
538
+ /// To prevent infinite recursion by enforcing ordering, this returns a
539
+ /// function that needs to be called with the list of fields on the object.
540
+ pub fn build_object_type_with_info < T > ( & mut self , info : & T :: TypeInfo , fields : & [ Field < ' r > ] ) -> ObjectMeta < ' r >
484
541
where T : GraphQLType
485
542
{
486
- let name = T :: name ( ) . expect ( "Object types must be named. Implement name()" ) ;
543
+ let name = T :: name ( info ) . expect ( "Object types must be named. Implement name()" ) ;
487
544
488
545
let mut v = fields. to_vec ( ) ;
489
546
v. push ( self . field :: < String > ( "__typename" ) ) ;
490
- ObjectMeta :: new ( name, & v)
547
+ ObjectMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , & v)
491
548
}
492
549
493
550
/// Create an enum meta type
494
551
pub fn build_enum_type < T > ( & mut self , values : & [ EnumValue ] ) -> EnumMeta < ' r >
552
+ where T : FromInputValue + GraphQLType < TypeInfo =( ) >
553
+ {
554
+ self . build_enum_type_with_info :: < T > ( & ( ) , values)
555
+ }
556
+
557
+ /// Create an enum meta type,
558
+ /// by providing a type info object.
559
+ pub fn build_enum_type_with_info < T > ( & mut self , info : & T :: TypeInfo , values : & [ EnumValue ] ) -> EnumMeta < ' r >
495
560
where T : FromInputValue + GraphQLType
496
561
{
497
- let name = T :: name ( ) . expect ( "Enum types must be named. Implement name()" ) ;
562
+ let name = T :: name ( info ) . expect ( "Enum types must be named. Implement name()" ) ;
498
563
499
- EnumMeta :: new :: < T > ( name, values)
564
+ EnumMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) , values)
500
565
}
501
566
502
567
/// Create an interface meta type builder
503
568
pub fn build_interface_type < T > ( & mut self , fields : & [ Field < ' r > ] ) -> InterfaceMeta < ' r >
569
+ where T : GraphQLType < TypeInfo =( ) >
570
+ {
571
+ self . build_interface_type_with_info :: < T > ( & ( ) , fields)
572
+ }
573
+
574
+ /// Create an interface meta type builder,
575
+ /// by providing a type info object.
576
+ pub fn build_interface_type_with_info < T > ( & mut self , info : & T :: TypeInfo , fields : & [ Field < ' r > ] ) -> InterfaceMeta < ' r >
504
577
where T : GraphQLType
505
578
{
506
- let name = T :: name ( ) . expect ( "Interface types must be named. Implement name()" ) ;
579
+ let name = T :: name ( info ) . expect ( "Interface types must be named. Implement name()" ) ;
507
580
508
581
let mut v = fields. to_vec ( ) ;
509
582
v. push ( self . field :: < String > ( "__typename" ) ) ;
510
- InterfaceMeta :: new ( name, & v)
583
+ InterfaceMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , & v)
511
584
}
512
585
513
586
/// Create a union meta type builder
514
587
pub fn build_union_type < T > ( & mut self , types : & [ Type < ' r > ] ) -> UnionMeta < ' r >
588
+ where T : GraphQLType < TypeInfo =( ) >
589
+ {
590
+ self . build_union_type_with_info :: < T > ( & ( ) , types)
591
+ }
592
+
593
+ /// Create a union meta type builder,
594
+ /// by providing a type info object.
595
+ pub fn build_union_type_with_info < T > ( & mut self , info : & T :: TypeInfo , types : & [ Type < ' r > ] ) -> UnionMeta < ' r >
515
596
where T : GraphQLType
516
597
{
517
- let name = T :: name ( ) . expect ( "Union types must be named. Implement name()" ) ;
598
+ let name = T :: name ( info ) . expect ( "Union types must be named. Implement name()" ) ;
518
599
519
- UnionMeta :: new ( name, types)
600
+ UnionMeta :: new ( Cow :: Owned ( name. to_string ( ) ) , types)
520
601
}
521
602
522
603
/// Create an input object meta type builder
523
604
pub fn build_input_object_type < T > ( & mut self , args : & [ Argument < ' r > ] ) -> InputObjectMeta < ' r >
605
+ where T : FromInputValue + GraphQLType < TypeInfo =( ) >
606
+ {
607
+ self . build_input_object_type_with_info :: < T > ( & ( ) , args)
608
+ }
609
+
610
+ /// Create an input object meta type builder,
611
+ /// by providing a type info object.
612
+ pub fn build_input_object_type_with_info < T > ( & mut self , info : & T :: TypeInfo , args : & [ Argument < ' r > ] ) -> InputObjectMeta < ' r >
524
613
where T : FromInputValue + GraphQLType
525
614
{
526
- let name = T :: name ( ) . expect ( "Input object types must be named. Implement name()" ) ;
615
+ let name = T :: name ( info ) . expect ( "Input object types must be named. Implement name()" ) ;
527
616
528
- InputObjectMeta :: new :: < T > ( name, args)
617
+ InputObjectMeta :: new :: < T > ( Cow :: Owned ( name. to_string ( ) ) , args)
529
618
}
530
619
}
0 commit comments