11use constants:: * ;
22use failure;
33use field_type:: FieldType ;
4- use heck:: { CamelCase , SnakeCase } ;
54use proc_macro2:: { Ident , Span , TokenStream } ;
65use query:: QueryContext ;
76use selection:: * ;
8- use shared:: render_object_field ;
7+ use shared:: { field_impls_for_selection , response_fields_for_selection } ;
98use std:: borrow:: Cow ;
109
1110#[ derive( Debug , PartialEq ) ]
@@ -14,7 +13,7 @@ pub struct GqlObject {
1413 pub fields : Vec < GqlObjectField > ,
1514}
1615
17- #[ derive( Debug , PartialEq , Hash ) ]
16+ #[ derive( Clone , Debug , PartialEq , Hash ) ]
1817pub struct GqlObjectField {
1918 pub name : String ,
2019 pub type_ : FieldType ,
@@ -24,12 +23,7 @@ impl GqlObject {
2423 pub fn new ( name : Cow < str > ) -> GqlObject {
2524 GqlObject {
2625 name : name. into_owned ( ) ,
27- fields : vec ! [ GqlObjectField {
28- name: TYPENAME_FIELD . to_string( ) ,
29- /// Non-nullable, see spec:
30- /// https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md
31- type_: FieldType :: Named ( string_type( ) ) ,
32- } ] ,
26+ fields : vec ! [ typename_field( ) ] ,
3327 }
3428 }
3529
@@ -64,7 +58,7 @@ impl GqlObject {
6458 prefix : & str ,
6559 ) -> Result < TokenStream , failure:: Error > {
6660 let name = Ident :: new ( prefix, Span :: call_site ( ) ) ;
67- let fields = self . response_fields_for_selection ( query_context, selection, prefix) ;
61+ let fields = self . response_fields_for_selection ( query_context, selection, prefix) ? ;
6862 let field_impls = self . field_impls_for_selection ( query_context, selection, & prefix) ?;
6963 Ok ( quote ! {
7064 #( #field_impls) *
@@ -82,69 +76,15 @@ impl GqlObject {
8276 selection : & Selection ,
8377 prefix : & str ,
8478 ) -> Result < Vec < TokenStream > , failure:: Error > {
85- selection
86- . 0
87- . iter ( )
88- . map ( |selected| {
89- if let SelectionItem :: Field ( selected) = selected {
90- let ty = self
91- . fields
92- . iter ( )
93- . find ( |f| f. name == selected. name )
94- . ok_or_else ( || format_err ! ( "could not find field `{}`" , selected. name) ) ?
95- . type_
96- . inner_name_string ( ) ;
97- let prefix = format ! (
98- "{}{}" ,
99- prefix. to_camel_case( ) ,
100- selected. name. to_camel_case( )
101- ) ;
102- query_context. maybe_expand_field ( & ty, & selected. fields , & prefix)
103- } else {
104- Ok ( quote ! ( ) )
105- }
106- } )
107- . collect ( )
79+ field_impls_for_selection ( & self . fields , query_context, selection, prefix)
10880 }
10981
11082 pub fn response_fields_for_selection (
11183 & self ,
11284 query_context : & QueryContext ,
11385 selection : & Selection ,
11486 prefix : & str ,
115- ) -> Vec < TokenStream > {
116- let mut fields = Vec :: new ( ) ;
117-
118- for item in selection. 0 . iter ( ) {
119- match item {
120- SelectionItem :: Field ( f) => {
121- let name = & f. name ;
122-
123- let ty = & self
124- . fields
125- . iter ( )
126- . find ( |field| field. name . as_str ( ) == name. as_str ( ) )
127- . expect ( "could not find field" )
128- . type_ ;
129- let ty = ty. to_rust (
130- query_context,
131- & format ! ( "{}{}" , prefix. to_camel_case( ) , name. to_camel_case( ) ) ,
132- ) ;
133- fields. push ( render_object_field ( name, ty) ) ;
134- }
135- SelectionItem :: FragmentSpread ( fragment) => {
136- let field_name =
137- Ident :: new ( & fragment. fragment_name . to_snake_case ( ) , Span :: call_site ( ) ) ;
138- let type_name = Ident :: new ( & fragment. fragment_name , Span :: call_site ( ) ) ;
139- fields. push ( quote ! {
140- #[ serde( flatten) ]
141- #field_name: #type_name
142- } )
143- }
144- SelectionItem :: InlineFragment ( _) => unreachable ! ( "inline fragment on object field" ) ,
145- }
146- }
147-
148- fields
87+ ) -> Result < Vec < TokenStream > , failure:: Error > {
88+ response_fields_for_selection ( & self . fields , query_context, selection, prefix)
14989 }
15090}
0 commit comments