@@ -339,17 +339,35 @@ impl<S> GraphQLValueAsync<S> for Json
339339 }
340340}
341341
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
343346 fn type_name ( ) -> & ' static str ;
347+
348+ /// schema returns the GrpahQL Schema Definition language that contains the type_name
344349 fn schema ( ) -> & ' static str ;
345350}
346351
352+ /// Wrapper generic type for serde_json::Value that associates
353+ /// type information.
347354#[ 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 ,
350358 phantom : PhantomData < T > ,
351359}
352360
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+
353371impl < T , S > IsOutputType < S > for TypedJson < T > where
354372 S : ScalarValue ,
355373 T : TypedJsonInfo ,
@@ -365,15 +383,10 @@ impl<T, S> FromInputValue<S> for TypedJson<T> where
365383 T : TypedJsonInfo ,
366384{
367385 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 ) )
369387 }
370388}
371389
372- impl < T , S > GraphQLValueAsync < S > for TypedJson < T > where
373- S : ScalarValue + Send + Sync ,
374- T : TypedJsonInfo
375- { }
376-
377390impl < T , S > GraphQLType < S > for TypedJson < T > where
378391 S : ScalarValue ,
379392 T : TypedJsonInfo ,
@@ -407,10 +420,44 @@ impl<T, S> GraphQLValue<S> for TypedJson<T>
407420 _selection : Option < & [ Selection < S > ] > ,
408421 executor : & Executor < Self :: Context , S > ,
409422 ) -> 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 )
411424 }
412425}
413426
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+
414461#[ cfg( test) ]
415462mod tests {
416463 use std:: marker:: PhantomData ;
@@ -420,8 +467,10 @@ mod tests {
420467 use juniper:: {
421468 integrations:: json:: { TypedJson , TypedJsonInfo , TypeInfo } ,
422469 EmptyMutation , EmptySubscription , execute_sync, FieldResult , graphql_object, graphql_value,
423- RootNode , ToInputValue , Variables ,
470+ RootNode , ToInputValue , Variables , graphql_subscription ,
424471 } ;
472+ use crate :: { Executor , ScalarValue , resolve_into_stream, Value , ValuesStream , ExecutionError , GraphQLError } ;
473+ use std:: pin:: Pin ;
425474
426475 #[ test]
427476 fn sdl_type_info ( ) {
@@ -680,7 +729,7 @@ mod tests {
680729 impl Query {
681730 fn foo ( ) -> FieldResult < TypedJson < Foo > > {
682731 let data = json ! ( { "message" : [ "Hello" , "World" ] } ) ;
683- Ok ( TypedJson { value : data , phantom : PhantomData } )
732+ Ok ( TypedJson :: new ( data ) )
684733 }
685734 }
686735 let schema = juniper:: RootNode :: new ( Query , EmptyMutation :: new ( ) , EmptySubscription :: new ( ) ) ;
@@ -725,7 +774,7 @@ mod tests {
725774 #[ graphql_object( ) ]
726775 impl Query {
727776 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" ] } ) ) )
729778 }
730779 }
731780 let schema = juniper:: RootNode :: new ( Query , EmptyMutation :: new ( ) , EmptySubscription :: new ( ) ) ;
0 commit comments