@@ -339,17 +339,35 @@ impl<S> GraphQLValueAsync<S> for Json
339
339
}
340
340
}
341
341
342
- trait TypedJsonInfo : Send + Sync {
342
+ /// Trait used to provide the type information for a
343
+ /// serde_json::Value
344
+ pub trait TypedJsonInfo : Send + Sync {
345
+ /// the GraphQL type name
343
346
fn type_name ( ) -> & ' static str ;
347
+
348
+ /// schema returns the GrpahQL Schema Definition language that contains the type_name
344
349
fn schema ( ) -> & ' static str ;
345
350
}
346
351
352
+ /// Wrapper generic type for serde_json::Value that associates
353
+ /// type information.
347
354
#[ derive( Debug , Clone , PartialEq ) ]
348
- struct TypedJson < T : TypedJsonInfo > {
349
- value : serde_json:: Value ,
355
+ pub struct TypedJson < T : TypedJsonInfo > {
356
+ /// the wrapped json value
357
+ pub json : serde_json:: Value ,
350
358
phantom : PhantomData < T > ,
351
359
}
352
360
361
+ impl < T : TypedJsonInfo > TypedJson < T > {
362
+ /// creates a new TypedJson from a serde_json::Value
363
+ pub fn new ( v : serde_json:: Value ) -> TypedJson < T > {
364
+ TypedJson {
365
+ json : v,
366
+ phantom : PhantomData ,
367
+ }
368
+ }
369
+ }
370
+
353
371
impl < T , S > IsOutputType < S > for TypedJson < T > where
354
372
S : ScalarValue ,
355
373
T : TypedJsonInfo ,
@@ -365,15 +383,10 @@ impl<T, S> FromInputValue<S> for TypedJson<T> where
365
383
T : TypedJsonInfo ,
366
384
{
367
385
fn from_input_value ( v : & InputValue < S > ) -> Option < Self > {
368
- <serde_json:: Value as FromInputValue < S > >:: from_input_value ( v) . map ( |x| TypedJson { value : x , phantom : PhantomData } )
386
+ <serde_json:: Value as FromInputValue < S > >:: from_input_value ( v) . map ( |x| TypedJson :: new ( x ) )
369
387
}
370
388
}
371
389
372
- impl < T , S > GraphQLValueAsync < S > for TypedJson < T > where
373
- S : ScalarValue + Send + Sync ,
374
- T : TypedJsonInfo
375
- { }
376
-
377
390
impl < T , S > GraphQLType < S > for TypedJson < T > where
378
391
S : ScalarValue ,
379
392
T : TypedJsonInfo ,
@@ -407,10 +420,44 @@ impl<T, S> GraphQLValue<S> for TypedJson<T>
407
420
_selection : Option < & [ Selection < S > ] > ,
408
421
executor : & Executor < Self :: Context , S > ,
409
422
) -> ExecutionResult < S > {
410
- executor. resolve ( & TypeInfo { schema : None , name : T :: type_name ( ) . to_string ( ) } , & self . value )
423
+ executor. resolve ( & TypeInfo { schema : None , name : T :: type_name ( ) . to_string ( ) } , & self . json )
411
424
}
412
425
}
413
426
427
+ impl < T , S > GraphQLValueAsync < S > for TypedJson < T >
428
+ where
429
+ Self :: TypeInfo : Sync ,
430
+ Self :: Context : Sync ,
431
+ S : ScalarValue + Send + Sync ,
432
+ T : TypedJsonInfo ,
433
+ {
434
+ fn resolve_async < ' a > (
435
+ & ' a self ,
436
+ _info : & ' a Self :: TypeInfo ,
437
+ selection_set : Option < & ' a [ Selection < S > ] > ,
438
+ executor : & ' a Executor < Self :: Context , S > ,
439
+ ) -> BoxFuture < ' a , ExecutionResult < S > > {
440
+ Box :: pin ( async move {
441
+ let info = TypeInfo { schema : None , name : T :: type_name ( ) . to_string ( ) } ;
442
+ <Json as GraphQLValue < S > >:: resolve ( & self . json , & info, selection_set, executor)
443
+ } )
444
+ }
445
+
446
+ fn resolve_field_async < ' a > (
447
+ & ' a self ,
448
+ _info : & ' a Self :: TypeInfo ,
449
+ field_name : & ' a str ,
450
+ arguments : & ' a Arguments < S > ,
451
+ executor : & ' a Executor < Self :: Context , S > ,
452
+ ) -> BoxFuture < ' a , ExecutionResult < S > > {
453
+ Box :: pin ( async move {
454
+ let info = TypeInfo { schema : None , name : T :: type_name ( ) . to_string ( ) } ;
455
+ <Json as GraphQLValue < S > >:: resolve_field ( & self . json , & info, field_name, arguments, executor)
456
+ } )
457
+ }
458
+ }
459
+
460
+
414
461
#[ cfg( test) ]
415
462
mod tests {
416
463
use std:: marker:: PhantomData ;
@@ -420,8 +467,10 @@ mod tests {
420
467
use juniper:: {
421
468
integrations:: json:: { TypedJson , TypedJsonInfo , TypeInfo } ,
422
469
EmptyMutation , EmptySubscription , execute_sync, FieldResult , graphql_object, graphql_value,
423
- RootNode , ToInputValue , Variables ,
470
+ RootNode , ToInputValue , Variables , graphql_subscription ,
424
471
} ;
472
+ use crate :: { Executor , ScalarValue , resolve_into_stream, Value , ValuesStream , ExecutionError , GraphQLError } ;
473
+ use std:: pin:: Pin ;
425
474
426
475
#[ test]
427
476
fn sdl_type_info ( ) {
@@ -680,7 +729,7 @@ mod tests {
680
729
impl Query {
681
730
fn foo ( ) -> FieldResult < TypedJson < Foo > > {
682
731
let data = json ! ( { "message" : [ "Hello" , "World" ] } ) ;
683
- Ok ( TypedJson { value : data , phantom : PhantomData } )
732
+ Ok ( TypedJson :: new ( data ) )
684
733
}
685
734
}
686
735
let schema = juniper:: RootNode :: new ( Query , EmptyMutation :: new ( ) , EmptySubscription :: new ( ) ) ;
@@ -725,7 +774,7 @@ mod tests {
725
774
#[ graphql_object( ) ]
726
775
impl Query {
727
776
fn foo ( value : TypedJson < Foo > ) -> FieldResult < bool > {
728
- Ok ( value == TypedJson { value : json ! ( { "message" : [ "Hello" , "World" ] } ) , phantom : PhantomData } )
777
+ Ok ( value == TypedJson :: new ( json ! ( { "message" : [ "Hello" , "World" ] } ) ) )
729
778
}
730
779
}
731
780
let schema = juniper:: RootNode :: new ( Query , EmptyMutation :: new ( ) , EmptySubscription :: new ( ) ) ;
0 commit comments