1- use crate :: graphql:: * ;
1+ use crate :: graphql:: { EnumSource , __InputValue , __Type , ___Type } ;
22use crate :: gson;
33use graphql_parser:: query:: * ;
4- use graphql_parser:: Pos ;
54use std:: collections:: HashMap ;
65
76pub fn alias_or_name < ' a , T > ( query_field : & graphql_parser:: query:: Field < ' a , T > ) -> String
@@ -15,221 +14,34 @@ where
1514 . unwrap_or_else ( || query_field. name . as_ref ( ) . to_string ( ) )
1615}
1716
18- pub fn merge_fields < ' a , T , I > (
19- target_fields : & mut Vec < Field < ' a , T > > ,
20- next_fields : I ,
21- type_name : & str ,
22- field_map : & HashMap < String , __Field > ,
23- ) -> Result < ( ) , String >
24- where
25- T : Text < ' a > + Eq + AsRef < str > + std:: fmt:: Debug + Clone ,
26- I : IntoIterator < Item = Field < ' a , T > > ,
27- {
28- for field in next_fields {
29- merge_field ( target_fields, field, type_name, field_map) ?
30- }
31- Ok ( ( ) )
32- }
33-
34- pub fn merge_field < ' a , T > (
35- target_fields : & mut Vec < Field < ' a , T > > ,
36- mut field : Field < ' a , T > ,
37- type_name : & str ,
38- field_map : & HashMap < String , __Field > ,
39- ) -> Result < ( ) , String >
40- where
41- T : Text < ' a > + Eq + AsRef < str > + std:: fmt:: Debug + Clone ,
42- {
43- let Some ( ( matching_idx, matching_field) ) = target_fields
44- . iter ( )
45- . enumerate ( )
46- . find ( |( _, target) | alias_or_name ( target) == alias_or_name ( & field) )
47- else {
48- target_fields. push ( field) ;
49- return Ok ( ( ) ) ;
50- } ;
51-
52- can_fields_merge ( matching_field, & field, type_name, field_map) ?;
53-
54- field. position = field. position . min ( matching_field. position ) ;
55-
56- field. selection_set . span =
57- min_encapsulating_span ( field. selection_set . span , matching_field. selection_set . span ) ;
58-
59- // Subfields will be normalized and properly merged on a later pass.
60- field
61- . selection_set
62- . items
63- . extend ( matching_field. selection_set . items . clone ( ) ) ;
64-
65- target_fields[ matching_idx] = field;
66-
67- Ok ( ( ) )
68- }
69-
70- pub fn can_fields_merge < ' a , T > (
71- field_a : & Field < ' a , T > ,
72- field_b : & Field < ' a , T > ,
73- type_name : & str ,
74- field_map : & HashMap < String , __Field > ,
75- ) -> Result < ( ) , String >
76- where
77- T : Text < ' a > + Eq + AsRef < str > + std:: fmt:: Debug + Clone ,
78- {
79- let Some ( _field_a) = field_map. get ( field_a. name . as_ref ( ) ) else {
80- return Err ( format ! (
81- "Unknown field '{}' on type '{}'" ,
82- field_a. name. as_ref( ) ,
83- type_name
84- ) ) ;
85- } ;
86- let Some ( _field_b) = field_map. get ( field_b. name . as_ref ( ) ) else {
87- return Err ( format ! (
88- "Unknown field '{}' on type '{}'" ,
89- field_b. name. as_ref( ) ,
90- type_name
91- ) ) ;
92- } ;
93-
94- has_same_type_shape (
95- & alias_or_name ( field_a) ,
96- type_name,
97- & _field_a. type_ ,
98- & _field_b. type_ ,
99- ) ?;
100-
101- if field_a. name != field_b. name {
102- return Err ( format ! (
103- "Fields '{}' on type '{}' conflict because '{}' and '{}' are different fields" ,
104- alias_or_name( field_a) ,
105- type_name,
106- field_a. name. as_ref( ) ,
107- field_b. name. as_ref( ) ,
108- ) ) ;
109- }
110-
111- for ( arg_a_name, arg_a_value) in field_a. arguments . iter ( ) {
112- let arg_b_value = field_b. arguments . iter ( ) . find_map ( |( name, value) | {
113- if name == arg_a_name {
114- Some ( value)
115- } else {
116- None
117- }
118- } ) ;
119- let args_match = match arg_b_value {
120- None => false ,
121- Some ( arg_b_value) => arg_b_value == arg_a_value,
122- } ;
123- if !args_match {
124- return Err ( format ! (
125- "Fields '{}' on type '{}' conflict because they have differing arguments" ,
126- alias_or_name( field_a) ,
127- type_name,
128- ) ) ;
129- }
130- }
131-
132- Ok ( ( ) )
133- }
134-
135- pub fn has_same_type_shape (
136- field_name : & str ,
137- type_name : & str ,
138- type_a : & __Type ,
139- type_b : & __Type ,
140- ) -> Result < ( ) , String > {
141- let mut type_a = type_a;
142- let mut type_b = type_b;
143-
144- if matches ! ( type_a, __Type:: NonNull ( _) ) || matches ! ( type_b, __Type:: NonNull ( _) ) {
145- if let ( __Type:: NonNull ( nullable_type_a) , __Type:: NonNull ( nullable_type_b) ) =
146- ( type_a, type_b)
147- {
148- type_a = nullable_type_a. type_ . as_ref ( ) ;
149- type_b = nullable_type_b. type_ . as_ref ( ) ;
150- } else {
151- return Err ( format ! (
152- "Fields '{}' on type '{}' conflict because only one is non nullable" ,
153- field_name, type_name,
154- ) ) ;
155- }
156- }
157-
158- if matches ! ( type_a, __Type:: List ( _) ) || matches ! ( type_b, __Type:: List ( _) ) {
159- if let ( __Type:: List ( list_type_a) , __Type:: List ( list_type_b) ) = ( type_a, type_b) {
160- type_a = list_type_a. type_ . as_ref ( ) ;
161- type_b = list_type_b. type_ . as_ref ( ) ;
162- } else {
163- return Err ( format ! (
164- "Fields '{}' on type '{}' conflict because only one is a list type" ,
165- field_name, type_name,
166- ) ) ;
167- }
168-
169- return has_same_type_shape ( field_name, type_name, type_a, type_b) ;
170- }
171-
172- if matches ! ( type_a, __Type:: Enum ( _) )
173- || matches ! ( type_b, __Type:: Enum ( _) )
174- || matches ! ( type_a, __Type:: Scalar ( _) )
175- || matches ! ( type_b, __Type:: Scalar ( _) )
176- {
177- return if type_a == type_b {
178- Ok ( ( ) )
179- } else {
180- Err ( format ! (
181- "Fields '{}' on type '{}' conflict due to mismatched types" ,
182- field_name, type_name,
183- ) )
184- } ;
185- }
186-
187- // TODO handle composite types?
188-
189- // Subfield type shapes will be checked on a later pass.
190- Ok ( ( ) )
191- }
192-
193- pub fn min_encapsulating_span ( a : ( Pos , Pos ) , b : ( Pos , Pos ) ) -> ( Pos , Pos ) {
194- ( a. 0 . min ( b. 0 ) , a. 1 . max ( b. 1 ) )
195- }
196-
197- pub fn normalize_selection_set < ' a , T > (
198- selection_set : & SelectionSet < ' a , T > ,
199- fragment_definitions : & Vec < FragmentDefinition < ' a , T > > ,
17+ pub fn normalize_selection_set < ' a , ' b , T > (
18+ selection_set : & ' b SelectionSet < ' a , T > ,
19+ fragment_definitions : & ' b Vec < FragmentDefinition < ' a , T > > ,
20020 type_name : & String , // for inline fragments
20121 variables : & serde_json:: Value , // for directives
202- field_type : & __Type ,
203- ) -> Result < Vec < Field < ' a , T > > , String >
22+ ) -> Result < Vec < & ' b Field < ' a , T > > , String >
20423where
205- T : Text < ' a > + Eq + AsRef < str > + std :: fmt :: Debug + Clone ,
24+ T : Text < ' a > + Eq + AsRef < str > ,
20625{
207- let mut normalized_fields: Vec < Field < ' a , T > > = vec ! [ ] ;
208-
209- let field_map = field_map ( & field_type. unmodified_type ( ) ) ;
26+ let mut selections: Vec < & ' b Field < ' a , T > > = vec ! [ ] ;
21027
21128 for selection in & selection_set. items {
212- match normalize_selection (
213- selection,
214- fragment_definitions,
215- type_name,
216- variables,
217- field_type,
218- ) {
219- Ok ( fields) => merge_fields ( & mut normalized_fields, fields, type_name, & field_map) ?,
29+ let sel = selection;
30+ match normalize_selection ( sel, fragment_definitions, type_name, variables) {
31+ Ok ( sels) => selections. extend ( sels) ,
22032 Err ( err) => return Err ( err) ,
22133 }
22234 }
223- Ok ( normalized_fields )
35+ Ok ( selections )
22436}
22537
22638/// Combines @skip and @include
227- pub fn selection_is_skipped < ' a , T > (
228- query_selection : & Selection < ' a , T > ,
39+ pub fn selection_is_skipped < ' a , ' b , T > (
40+ query_selection : & ' b Selection < ' a , T > ,
22941 variables : & serde_json:: Value ,
23042) -> Result < bool , String >
23143where
232- T : Text < ' a > + Eq + AsRef < str > + std :: fmt :: Debug ,
44+ T : Text < ' a > + Eq + AsRef < str > ,
23345{
23446 let directives = match query_selection {
23547 Selection :: Field ( x) => & x. directives ,
@@ -318,27 +130,24 @@ where
318130}
319131
320132/// Normalizes literal selections, fragment spreads, and inline fragments
321- pub fn normalize_selection < ' a , T > (
322- query_selection : & Selection < ' a , T > ,
323- fragment_definitions : & Vec < FragmentDefinition < ' a , T > > ,
133+ pub fn normalize_selection < ' a , ' b , T > (
134+ query_selection : & ' b Selection < ' a , T > ,
135+ fragment_definitions : & ' b Vec < FragmentDefinition < ' a , T > > ,
324136 type_name : & String , // for inline fragments
325137 variables : & serde_json:: Value , // for directives
326- field_type : & __Type , // for field merging shape check
327- ) -> Result < Vec < Field < ' a , T > > , String >
138+ ) -> Result < Vec < & ' b Field < ' a , T > > , String >
328139where
329- T : Text < ' a > + Eq + AsRef < str > + std :: fmt :: Debug + Clone ,
140+ T : Text < ' a > + Eq + AsRef < str > ,
330141{
331- let mut normalized_fields : Vec < Field < ' a , T > > = vec ! [ ] ;
142+ let mut selections : Vec < & Field < ' a , T > > = vec ! [ ] ;
332143
333144 if selection_is_skipped ( query_selection, variables) ? {
334- return Ok ( normalized_fields ) ;
145+ return Ok ( selections ) ;
335146 }
336147
337- let field_map = field_map ( & field_type. unmodified_type ( ) ) ;
338-
339148 match query_selection {
340149 Selection :: Field ( field) => {
341- merge_field ( & mut normalized_fields , field . clone ( ) , type_name , & field_map ) ? ;
150+ selections . push ( field ) ;
342151 }
343152 Selection :: FragmentSpread ( fragment_spread) => {
344153 let frag_name = & fragment_spread. fragment_name ;
@@ -364,15 +173,14 @@ where
364173 } ;
365174
366175 // TODO handle directives?
367- let frag_fields = normalize_selection_set (
176+ let frag_selections = normalize_selection_set (
368177 & frag_def. selection_set ,
369178 fragment_definitions,
370179 type_name,
371180 variables,
372- field_type,
373181 ) ;
374- match frag_fields {
375- Ok ( fields ) => merge_fields ( & mut normalized_fields , fields , type_name , & field_map ) ? ,
182+ match frag_selections {
183+ Ok ( sels ) => selections . extend ( sels . iter ( ) ) ,
376184 Err ( err) => return Err ( err) ,
377185 } ;
378186 }
@@ -385,19 +193,18 @@ where
385193 } ;
386194
387195 if inline_fragment_applies {
388- let infrag_fields = normalize_selection_set (
196+ let infrag_selections = normalize_selection_set (
389197 & inline_fragment. selection_set ,
390198 fragment_definitions,
391199 type_name,
392200 variables,
393- field_type,
394201 ) ?;
395- merge_fields ( & mut normalized_fields , infrag_fields , type_name , & field_map ) ? ;
202+ selections . extend ( infrag_selections . iter ( ) ) ;
396203 }
397204 }
398205 }
399206
400- Ok ( normalized_fields )
207+ Ok ( selections )
401208}
402209
403210pub fn to_gson < ' a , T > (
@@ -406,7 +213,7 @@ pub fn to_gson<'a, T>(
406213 variable_definitions : & Vec < VariableDefinition < ' a , T > > ,
407214) -> Result < gson:: Value , String >
408215where
409- T : Text < ' a > + AsRef < str > + std :: fmt :: Debug ,
216+ T : Text < ' a > + AsRef < str > ,
410217{
411218 let result = match graphql_value {
412219 Value :: Null => gson:: Value :: Null ,
@@ -466,6 +273,7 @@ where
466273}
467274
468275pub fn validate_arg_from_type ( type_ : & __Type , value : & gson:: Value ) -> Result < gson:: Value , String > {
276+ use crate :: graphql:: Scalar ;
469277 use crate :: gson:: Number as GsonNumber ;
470278 use crate :: gson:: Value as GsonValue ;
471279
@@ -676,6 +484,7 @@ pub fn validate_arg_from_input_object(
676484 input_type : & __Type ,
677485 value : & gson:: Value ,
678486) -> Result < gson:: Value , String > {
487+ use crate :: graphql:: __TypeKind;
679488 use crate :: gson:: Value as GsonValue ;
680489
681490 let input_type_name = input_type. name ( ) . unwrap_or_default ( ) ;
0 commit comments