1
1
use std:: collections:: HashMap ;
2
- use std:: marker:: PhantomData ;
3
2
use std:: sync:: RwLock ;
4
3
5
4
use :: GraphQLError ;
@@ -20,10 +19,9 @@ use types::base::GraphQLType;
20
19
/// The registry gathers metadata for all types in a schema. It provides
21
20
/// convenience methods to convert types implementing the `GraphQLType` trait
22
21
/// into `Type` instances and automatically registers them.
23
- pub struct Registry < CtxT > {
22
+ pub struct Registry {
24
23
/// Currently registered types
25
24
pub types : HashMap < String , MetaType > ,
26
- phantom : PhantomData < CtxT > ,
27
25
}
28
26
29
27
#[ derive( Clone ) ]
@@ -80,9 +78,46 @@ impl<T> IntoFieldResult<T> for FieldResult<T> {
80
78
}
81
79
}
82
80
81
+ /// Conversion trait for context types
82
+ ///
83
+ /// This is currently only used for converting arbitrary contexts into
84
+ /// the empty tuple, but will in the future be used to support general
85
+ /// context conversion for larger schemas.
86
+ pub trait FromContext < T > {
87
+ /// Perform the conversion
88
+ fn from_context ( value : & T ) -> & Self ;
89
+ }
90
+
91
+ /// Marker trait for types that can act as context objects for GraphQL types.
92
+ pub trait Context { }
93
+
94
+ static NULL_CONTEXT : ( ) = ( ) ;
95
+
96
+ impl < T > FromContext < T > for ( ) {
97
+ fn from_context ( _: & T ) -> & Self {
98
+ & NULL_CONTEXT
99
+ }
100
+ }
101
+
102
+ impl < T > FromContext < T > for T where T : Context {
103
+ fn from_context ( value : & T ) -> & Self {
104
+ value
105
+ }
106
+ }
107
+
83
108
impl < ' a , CtxT > Executor < ' a , CtxT > {
109
+ /// Resolve a single arbitrary value, mapping the context to a new type
110
+ pub fn resolve_with_ctx < NewCtxT , T : GraphQLType < Context =NewCtxT > > (
111
+ & self , value : & T
112
+ ) -> ExecutionResult
113
+ where NewCtxT : FromContext < CtxT > ,
114
+ {
115
+ self . replaced_context ( <NewCtxT as FromContext < CtxT > >:: from_context ( & self . context ) )
116
+ . resolve ( value)
117
+ }
118
+
84
119
/// Resolve a single arbitrary value into an `ExecutionResult`
85
- pub fn resolve < T : GraphQLType < CtxT > > ( & self , value : & T ) -> ExecutionResult {
120
+ pub fn resolve < T : GraphQLType < Context = CtxT > > ( & self , value : & T ) -> ExecutionResult {
86
121
Ok ( value. resolve (
87
122
match self . current_selection_set {
88
123
Some ( ref sel) => Some ( sel. clone ( ) ) ,
@@ -94,7 +129,7 @@ impl<'a, CtxT> Executor<'a, CtxT> {
94
129
/// Resolve a single arbitrary value into a return value
95
130
///
96
131
/// If the field fails to resolve, `null` will be returned.
97
- pub fn resolve_into_value < T : GraphQLType < CtxT > > ( & self , value : & T ) -> Value {
132
+ pub fn resolve_into_value < T : GraphQLType < Context = CtxT > > ( & self , value : & T ) -> Value {
98
133
match self . resolve ( value) {
99
134
Ok ( v) => v,
100
135
Err ( e) => {
@@ -230,13 +265,13 @@ impl ExecutionError {
230
265
pub fn execute_validated_query < ' a , QueryT , MutationT , CtxT > (
231
266
document : Document ,
232
267
operation_name : Option < & str > ,
233
- root_node : & RootNode < CtxT , QueryT , MutationT > ,
268
+ root_node : & RootNode < QueryT , MutationT > ,
234
269
variables : & HashMap < String , InputValue > ,
235
270
context : & CtxT
236
271
)
237
272
-> Result < ( Value , Vec < ExecutionError > ) , GraphQLError < ' a > >
238
- where QueryT : GraphQLType < CtxT > ,
239
- MutationT : GraphQLType < CtxT >
273
+ where QueryT : GraphQLType < Context = CtxT > ,
274
+ MutationT : GraphQLType < Context = CtxT >
240
275
{
241
276
let mut fragments = vec ! [ ] ;
242
277
let mut operation = None ;
@@ -290,20 +325,19 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
290
325
Ok ( ( value, errors) )
291
326
}
292
327
293
- impl < CtxT > Registry < CtxT > {
328
+ impl Registry {
294
329
/// Construct a new registry
295
- pub fn new ( types : HashMap < String , MetaType > ) -> Registry < CtxT > {
330
+ pub fn new ( types : HashMap < String , MetaType > ) -> Registry {
296
331
Registry {
297
332
types : types,
298
- phantom : PhantomData ,
299
333
}
300
334
}
301
335
302
336
/// Get the `Type` instance for a given GraphQL type
303
337
///
304
338
/// If the registry hasn't seen a type with this name before, it will
305
339
/// construct its metadata and store it.
306
- pub fn get_type < T > ( & mut self ) -> Type where T : GraphQLType < CtxT > {
340
+ pub fn get_type < T > ( & mut self ) -> Type where T : GraphQLType {
307
341
if let Some ( name) = T :: name ( ) {
308
342
if !self . types . contains_key ( name) {
309
343
self . insert_placeholder ( name, Type :: NonNullNamed ( name. to_owned ( ) ) ) ;
@@ -318,7 +352,7 @@ impl<CtxT> Registry<CtxT> {
318
352
}
319
353
320
354
/// Create a field with the provided name
321
- pub fn field < T > ( & mut self , name : & str ) -> Field where T : GraphQLType < CtxT > {
355
+ pub fn field < T > ( & mut self , name : & str ) -> Field where T : GraphQLType {
322
356
Field {
323
357
name : name. to_owned ( ) ,
324
358
description : None ,
@@ -329,7 +363,7 @@ impl<CtxT> Registry<CtxT> {
329
363
}
330
364
331
365
#[ doc( hidden) ]
332
- pub fn field_convert < T : IntoFieldResult < I > , I > ( & mut self , name : & str ) -> Field where I : GraphQLType < CtxT > {
366
+ pub fn field_convert < T : IntoFieldResult < I > , I > ( & mut self , name : & str ) -> Field where I : GraphQLType {
333
367
Field {
334
368
name : name. to_owned ( ) ,
335
369
description : None ,
@@ -340,7 +374,7 @@ impl<CtxT> Registry<CtxT> {
340
374
}
341
375
342
376
#[ doc( hidden) ]
343
- pub fn field_inside_result < T > ( & mut self , name : & str , _: FieldResult < T > ) -> Field where T : GraphQLType < CtxT > {
377
+ pub fn field_inside_result < T > ( & mut self , name : & str , _: FieldResult < T > ) -> Field where T : GraphQLType {
344
378
Field {
345
379
name : name. to_owned ( ) ,
346
380
description : None ,
@@ -351,7 +385,7 @@ impl<CtxT> Registry<CtxT> {
351
385
}
352
386
353
387
/// Create an argument with the provided name
354
- pub fn arg < T > ( & mut self , name : & str ) -> Argument where T : GraphQLType < CtxT > + FromInputValue {
388
+ pub fn arg < T > ( & mut self , name : & str ) -> Argument where T : GraphQLType + FromInputValue {
355
389
Argument :: new ( name, self . get_type :: < T > ( ) )
356
390
}
357
391
@@ -365,7 +399,7 @@ impl<CtxT> Registry<CtxT> {
365
399
value : & T ,
366
400
)
367
401
-> Argument
368
- where T : GraphQLType < CtxT > + ToInputValue + FromInputValue
402
+ where T : GraphQLType + ToInputValue + FromInputValue
369
403
{
370
404
Argument :: new ( name, self . get_type :: < Option < T > > ( ) )
371
405
. default_value ( value. to ( ) )
@@ -384,20 +418,20 @@ impl<CtxT> Registry<CtxT> {
384
418
/// This expects the type to implement `FromInputValue`.
385
419
pub fn build_scalar_type < T > ( & mut self )
386
420
-> ScalarMeta
387
- where T : FromInputValue + GraphQLType < CtxT >
421
+ where T : FromInputValue + GraphQLType
388
422
{
389
423
let name = T :: name ( ) . expect ( "Scalar types must be named. Implement name()" ) ;
390
424
ScalarMeta :: new :: < T > ( name)
391
425
}
392
426
393
427
/// Create a list meta type
394
- pub fn build_list_type < T : GraphQLType < CtxT > > ( & mut self ) -> ListMeta {
428
+ pub fn build_list_type < T : GraphQLType > ( & mut self ) -> ListMeta {
395
429
let of_type = self . get_type :: < T > ( ) ;
396
430
ListMeta :: new ( of_type)
397
431
}
398
432
399
433
/// Create a nullable meta type
400
- pub fn build_nullable_type < T : GraphQLType < CtxT > > ( & mut self ) -> NullableMeta {
434
+ pub fn build_nullable_type < T : GraphQLType > ( & mut self ) -> NullableMeta {
401
435
let of_type = self . get_type :: < T > ( ) ;
402
436
NullableMeta :: new ( of_type)
403
437
}
@@ -408,7 +442,7 @@ impl<CtxT> Registry<CtxT> {
408
442
/// function that needs to be called with the list of fields on the object.
409
443
pub fn build_object_type < T > ( & mut self )
410
444
-> Box < Fn ( & [ Field ] ) -> ObjectMeta >
411
- where T : GraphQLType < CtxT >
445
+ where T : GraphQLType
412
446
{
413
447
let name = T :: name ( ) . expect ( "Object types must be named. Implement name()" ) ;
414
448
let typename_field = self . field :: < String > ( "__typename" ) ;
@@ -423,7 +457,7 @@ impl<CtxT> Registry<CtxT> {
423
457
/// Create an enum meta type
424
458
pub fn build_enum_type < T > ( & mut self )
425
459
-> Box < Fn ( & [ EnumValue ] ) -> EnumMeta >
426
- where T : FromInputValue + GraphQLType < CtxT >
460
+ where T : FromInputValue + GraphQLType
427
461
{
428
462
let name = T :: name ( ) . expect ( "Enum types must be named. Implement name()" ) ;
429
463
@@ -433,7 +467,7 @@ impl<CtxT> Registry<CtxT> {
433
467
/// Create an interface meta type builder
434
468
pub fn build_interface_type < T > ( & mut self )
435
469
-> Box < Fn ( & [ Field ] ) -> InterfaceMeta >
436
- where T : GraphQLType < CtxT >
470
+ where T : GraphQLType
437
471
{
438
472
let name = T :: name ( ) . expect ( "Interface types must be named. Implement name()" ) ;
439
473
let typename_field = self . field :: < String > ( "__typename" ) ;
@@ -448,7 +482,7 @@ impl<CtxT> Registry<CtxT> {
448
482
/// Create a union meta type builder
449
483
pub fn build_union_type < T > ( & mut self )
450
484
-> Box < Fn ( & [ Type ] ) -> UnionMeta >
451
- where T : GraphQLType < CtxT >
485
+ where T : GraphQLType
452
486
{
453
487
let name = T :: name ( ) . expect ( "Union types must be named. Implement name()" ) ;
454
488
@@ -458,7 +492,7 @@ impl<CtxT> Registry<CtxT> {
458
492
/// Create an input object meta type builder
459
493
pub fn build_input_object_type < T > ( & mut self )
460
494
-> Box < Fn ( & [ Argument ] ) -> InputObjectMeta >
461
- where T : FromInputValue + GraphQLType < CtxT >
495
+ where T : FromInputValue + GraphQLType
462
496
{
463
497
let name = T :: name ( ) . expect ( "Input object types must be named. Implement name()" ) ;
464
498
0 commit comments