1- use query:: QueryContext ;
1+ use failure;
2+ use graphql_parser;
3+ use introspection_response;
24use objects:: GqlObjectField ;
35use proc_macro2:: { Ident , Span , TokenStream } ;
4- use introspection_response ;
5- use graphql_parser ;
6+ use query :: QueryContext ;
7+ use std :: collections :: HashMap ;
68
79#[ derive( Debug , PartialEq ) ]
810pub struct GqlInput {
911 pub name : String ,
10- pub fields : Vec < GqlObjectField > ,
12+ pub fields : HashMap < String , GqlObjectField > ,
1113}
1214
1315impl GqlInput {
14- pub fn to_rust ( & self , context : & QueryContext ) -> TokenStream {
16+ pub fn to_rust ( & self , context : & QueryContext ) -> Result < TokenStream , failure :: Error > {
1517 let name = Ident :: new ( & self . name , Span :: call_site ( ) ) ;
16- let fields = self . fields . iter ( ) . map ( |field| {
18+ let mut fields: Vec < & GqlObjectField > = self . fields . values ( ) . collect ( ) ;
19+ fields. sort_unstable_by ( |a, b| a. name . cmp ( & b. name ) ) ;
20+ let fields = fields. iter ( ) . map ( |field| {
1721 let ty = field. type_ . to_rust ( & context, "" ) ;
1822 let name = Ident :: new ( & field. name , Span :: call_site ( ) ) ;
19- quote ! ( #ty : #name )
23+ quote ! ( #name : #ty )
2024 } ) ;
2125
22- quote ! {
26+ Ok ( quote ! {
2327 #[ derive( Debug , Serialize ) ]
2428 #[ serde( rename_all = "camelCase" ) ]
2529 pub struct #name {
2630 #( #fields, ) *
2731 }
28- }
32+ } )
2933 }
3034}
3135
3236impl :: std:: convert:: From < graphql_parser:: schema:: InputObjectType > for GqlInput {
3337 fn from ( schema_input : graphql_parser:: schema:: InputObjectType ) -> GqlInput {
34- unimplemented ! ( ) ;
38+ GqlInput {
39+ name : schema_input. name ,
40+ fields : schema_input
41+ . fields
42+ . into_iter ( )
43+ . map ( |field| {
44+ let name = field. name . clone ( ) ;
45+ let field = GqlObjectField {
46+ name : field. name ,
47+ type_ : field. value_type . into ( ) ,
48+ } ;
49+ ( name, field)
50+ } )
51+ . collect ( ) ,
52+ }
3553 }
3654}
3755
3856impl :: std:: convert:: From < introspection_response:: FullType > for GqlInput {
3957 fn from ( schema_input : introspection_response:: FullType ) -> GqlInput {
40- unimplemented ! ( ) ;
58+ GqlInput {
59+ name : schema_input. name . expect ( "unnamed input object" ) ,
60+ fields : schema_input
61+ . input_fields
62+ . expect ( "fields on input object" )
63+ . into_iter ( )
64+ . filter_map ( |a| a)
65+ . map ( |f| {
66+ let name = f. input_value . name . expect ( "unnamed input object field" ) ;
67+ let field = GqlObjectField {
68+ name : name. clone ( ) ,
69+ type_ : f
70+ . input_value
71+ . type_
72+ . expect ( "type on input object field" )
73+ . into ( ) ,
74+ } ;
75+ ( name, field)
76+ } )
77+ . collect ( ) ,
78+ }
4179 }
4280}
4381
@@ -49,30 +87,66 @@ mod tests {
4987
5088 #[ test]
5189 fn gql_input_to_rust ( ) {
52- let input = GqlInput {
90+ let cat = GqlInput {
5391 name : "Cat" . to_string ( ) ,
5492 fields : vec ! [
55- GqlObjectField {
56- name: "pawsCount" . to_string( ) ,
57- type_: FieldType :: Named ( float_type( ) )
58- } ,
59- GqlObjectField {
60- name: "offsprings" . to_string( ) ,
61- type_: FieldType :: Vector ( Box :: new( FieldType :: Named ( Ident :: new( "Cat" , Span :: call_site( ) ) ) ) ) ,
62- } ,
63- GqlObjectField {
64- name: "requirements" . to_string( ) ,
65- type_: FieldType :: Optional ( Box :: new( FieldType :: Named ( Ident :: new( "CatRequirements" , Span :: call_site( ) ) ) ) ) ,
66- } ,
67- ] ,
93+ (
94+ "pawsCount" . to_string( ) ,
95+ GqlObjectField {
96+ name: "pawsCount" . to_string( ) ,
97+ type_: FieldType :: Named ( float_type( ) ) ,
98+ } ,
99+ ) ,
100+ (
101+ "offsprings" . to_string( ) ,
102+ GqlObjectField {
103+ name: "offsprings" . to_string( ) ,
104+ type_: FieldType :: Vector ( Box :: new( FieldType :: Named ( Ident :: new(
105+ "Cat" ,
106+ Span :: call_site( ) ,
107+ ) ) ) ) ,
108+ } ,
109+ ) ,
110+ (
111+ "requirements" . to_string( ) ,
112+ GqlObjectField {
113+ name: "requirements" . to_string( ) ,
114+ type_: FieldType :: Optional ( Box :: new( FieldType :: Named ( Ident :: new(
115+ "CatRequirements" ,
116+ Span :: call_site( ) ,
117+ ) ) ) ) ,
118+ } ,
119+ ) ,
120+ ] . into_iter ( )
121+ . collect ( ) ,
68122 } ;
69123
70-
71124 let expected: String = vec ! [
72- "" ,
73- "" ,
74- ] . into_iter ( ) . collect ( ) ;
125+ "# [ derive ( Debug , Serialize ) ] " ,
126+ "# [ serde ( rename_all = \" camelCase\" ) ] " ,
127+ "pub struct Cat { " ,
128+ "offsprings : Vec < Cat > , " ,
129+ "pawsCount : Float , " ,
130+ "requirements : Option < CatRequirements > , " ,
131+ "}" ,
132+ ] . into_iter ( )
133+ . collect ( ) ;
134+
135+ let mut context = QueryContext :: new_empty ( ) ;
136+ context. schema . inputs . insert ( cat. name . clone ( ) , cat) ;
75137
76- assert_eq ! ( format!( "{:?}" , input. to_rust( ) ) , expected) ;
138+ assert_eq ! (
139+ format!(
140+ "{}" ,
141+ context
142+ . schema
143+ . inputs
144+ . get( "Cat" )
145+ . unwrap( )
146+ . to_rust( & context)
147+ . unwrap( )
148+ ) ,
149+ expected
150+ ) ;
77151 }
78152}
0 commit comments