1
1
use ast:: { Directive , Fragment , InputValue , Selection } ;
2
2
use parser:: Spanning ;
3
+ use value:: ScalarValue ;
3
4
4
5
use std:: collections:: HashMap ;
5
6
@@ -21,25 +22,22 @@ pub enum Applies<'a> {
21
22
/// meaning that variables are already resolved.
22
23
#[ derive( Debug , Clone , PartialEq ) ]
23
24
#[ allow( missing_docs) ]
24
- pub enum LookAheadValue < ' a > {
25
+ pub enum LookAheadValue < ' a , S : ' a > {
25
26
Null ,
26
- Int ( i32 ) ,
27
- Float ( f64 ) ,
28
- String ( & ' a str ) ,
29
- Boolean ( bool ) ,
27
+ Scalar ( & ' a S ) ,
30
28
Enum ( & ' a str ) ,
31
- List ( Vec < LookAheadValue < ' a > > ) ,
32
- Object ( Vec < ( & ' a str , LookAheadValue < ' a > ) > ) ,
29
+ List ( Vec < LookAheadValue < ' a , S > > ) ,
30
+ Object ( Vec < ( & ' a str , LookAheadValue < ' a , S > ) > ) ,
33
31
}
34
32
35
- impl < ' a > LookAheadValue < ' a > {
36
- fn from_input_value ( input_value : & ' a InputValue , vars : & ' a Variables ) -> Self {
33
+ impl < ' a , S > LookAheadValue < ' a , S >
34
+ where
35
+ S : ScalarValue ,
36
+ {
37
+ fn from_input_value ( input_value : & ' a InputValue < S > , vars : & ' a Variables < S > ) -> Self {
37
38
match * input_value {
38
39
InputValue :: Null => LookAheadValue :: Null ,
39
- InputValue :: Int ( i) => LookAheadValue :: Int ( i) ,
40
- InputValue :: Float ( f) => LookAheadValue :: Float ( f) ,
41
- InputValue :: String ( ref s) => LookAheadValue :: String ( s) ,
42
- InputValue :: Boolean ( b) => LookAheadValue :: Boolean ( b) ,
40
+ InputValue :: Scalar ( ref s) => LookAheadValue :: Scalar ( s) ,
43
41
InputValue :: Enum ( ref e) => LookAheadValue :: Enum ( e) ,
44
42
InputValue :: Variable ( ref v) => Self :: from_input_value ( vars. get ( v) . unwrap ( ) , vars) ,
45
43
InputValue :: List ( ref l) => LookAheadValue :: List (
@@ -54,24 +52,26 @@ impl<'a> LookAheadValue<'a> {
54
52
& n. item as & str ,
55
53
LookAheadValue :: from_input_value ( & i. item , vars) ,
56
54
)
57
- } )
58
- . collect ( ) ,
55
+ } ) . collect ( ) ,
59
56
) ,
60
57
}
61
58
}
62
59
}
63
60
64
61
/// An argument passed into the query
65
62
#[ derive( Debug , Clone , PartialEq ) ]
66
- pub struct LookAheadArgument < ' a > {
63
+ pub struct LookAheadArgument < ' a , S : ' a > {
67
64
name : & ' a str ,
68
- value : LookAheadValue < ' a > ,
65
+ value : LookAheadValue < ' a , S > ,
69
66
}
70
67
71
- impl < ' a > LookAheadArgument < ' a > {
68
+ impl < ' a , S > LookAheadArgument < ' a , S >
69
+ where
70
+ S : ScalarValue ,
71
+ {
72
72
pub ( super ) fn new (
73
- & ( ref name, ref value) : & ' a ( Spanning < & ' a str > , Spanning < InputValue > ) ,
74
- vars : & ' a Variables ,
73
+ & ( ref name, ref value) : & ' a ( Spanning < & ' a str > , Spanning < InputValue < S > > ) ,
74
+ vars : & ' a Variables < S > ,
75
75
) -> Self {
76
76
LookAheadArgument {
77
77
name : name. item ,
@@ -80,86 +80,96 @@ impl<'a> LookAheadArgument<'a> {
80
80
}
81
81
82
82
/// The value of the argument
83
- pub fn value ( & ' a self ) -> & LookAheadValue < ' a > {
83
+ pub fn value ( & ' a self ) -> & LookAheadValue < ' a , S > {
84
84
& self . value
85
85
}
86
86
}
87
87
88
88
#[ derive( Debug , Clone , PartialEq ) ]
89
- pub struct ChildSelection < ' a > {
90
- pub ( super ) inner : LookAheadSelection < ' a > ,
89
+ pub struct ChildSelection < ' a , S : ' a > {
90
+ pub ( super ) inner : LookAheadSelection < ' a , S > ,
91
91
pub ( super ) applies_for : Applies < ' a > ,
92
92
}
93
93
94
94
/// A selection performed by a query
95
95
#[ derive( Debug , Clone , PartialEq ) ]
96
- pub struct LookAheadSelection < ' a > {
96
+ pub struct LookAheadSelection < ' a , S : ' a > {
97
97
pub ( super ) name : & ' a str ,
98
98
pub ( super ) alias : Option < & ' a str > ,
99
- pub ( super ) arguments : Vec < LookAheadArgument < ' a > > ,
100
- pub ( super ) children : Vec < ChildSelection < ' a > > ,
99
+ pub ( super ) arguments : Vec < LookAheadArgument < ' a , S > > ,
100
+ pub ( super ) children : Vec < ChildSelection < ' a , S > > ,
101
101
}
102
102
103
- impl < ' a > LookAheadSelection < ' a > {
104
- fn should_include ( directives : Option < & Vec < Spanning < Directive > > > , vars : & Variables ) -> bool {
103
+ impl < ' a , S > LookAheadSelection < ' a , S >
104
+ where
105
+ S : ScalarValue ,
106
+ & ' a S : Into < Option < bool > > ,
107
+ {
108
+ fn should_include < ' b , ' c > (
109
+ directives : Option < & ' b Vec < Spanning < Directive < S > > > > ,
110
+ vars : & ' c Variables < S > ,
111
+ ) -> bool
112
+ where
113
+ ' b : ' a ,
114
+ ' c : ' a ,
115
+ {
105
116
directives
106
117
. map ( |d| {
107
118
d. iter ( ) . all ( |d| {
108
119
let d = & d. item ;
109
120
let arguments = & d. arguments ;
110
121
match ( d. name . item , arguments) {
111
- ( "include" , & Some ( ref a) ) => a. item
122
+ ( "include" , & Some ( ref a) ) => a
123
+ . item
112
124
. items
113
125
. iter ( )
114
126
. find ( |item| item. 0 . item == "if" )
115
127
. map ( |& ( _, ref v) | {
116
- if let LookAheadValue :: Boolean ( b ) =
128
+ if let LookAheadValue :: Scalar ( s ) =
117
129
LookAheadValue :: from_input_value ( & v. item , vars)
118
130
{
119
- b
131
+ s . into ( ) . unwrap_or ( false )
120
132
} else {
121
133
false
122
134
}
123
- } )
124
- . unwrap_or ( false ) ,
125
- ( "skip" , & Some ( ref a ) ) => a . item
135
+ } ) . unwrap_or ( false ) ,
136
+ ( "skip" , & Some ( ref a ) ) => a
137
+ . item
126
138
. items
127
139
. iter ( )
128
140
. find ( |item| item. 0 . item == "if" )
129
141
. map ( |& ( _, ref v) | {
130
- if let LookAheadValue :: Boolean ( b) =
142
+ if let LookAheadValue :: Scalar ( b) =
131
143
LookAheadValue :: from_input_value ( & v. item , vars)
132
144
{
133
- !b
145
+ b . into ( ) . map ( :: std :: ops :: Not :: not ) . unwrap_or ( false )
134
146
} else {
135
147
false
136
148
}
137
- } )
138
- . unwrap_or ( false ) ,
149
+ } ) . unwrap_or ( false ) ,
139
150
( "skip" , & None ) => false ,
140
151
( "include" , & None ) => true ,
141
152
( _, _) => unreachable ! ( ) ,
142
153
}
143
154
} )
144
- } )
145
- . unwrap_or ( true )
155
+ } ) . unwrap_or ( true )
146
156
}
147
157
148
158
pub ( super ) fn build_from_selection (
149
- s : & ' a Selection < ' a > ,
150
- vars : & ' a Variables ,
151
- fragments : & ' a HashMap < & ' a str , & ' a Fragment < ' a > > ,
152
- ) -> LookAheadSelection < ' a > {
159
+ s : & ' a Selection < ' a , S > ,
160
+ vars : & ' a Variables < S > ,
161
+ fragments : & ' a HashMap < & ' a str , & ' a Fragment < ' a , S > > ,
162
+ ) -> LookAheadSelection < ' a , S > {
153
163
Self :: build_from_selection_with_parent ( s, None , vars, fragments) . unwrap ( )
154
164
}
155
165
156
166
fn build_from_selection_with_parent (
157
- s : & ' a Selection < ' a > ,
167
+ s : & ' a Selection < ' a , S > ,
158
168
parent : Option < & mut Self > ,
159
- vars : & ' a Variables ,
160
- fragments : & ' a HashMap < & ' a str , & ' a Fragment < ' a > > ,
161
- ) -> Option < LookAheadSelection < ' a > > {
162
- let empty: & [ Selection ] = & [ ] ;
169
+ vars : & ' a Variables < S > ,
170
+ fragments : & ' a HashMap < & ' a str , & ' a Fragment < ' a , S > > ,
171
+ ) -> Option < LookAheadSelection < ' a , S > > {
172
+ let empty: & [ Selection < S > ] = & [ ] ;
163
173
match * s {
164
174
Selection :: Field ( ref field) => {
165
175
let field = & field. item ;
@@ -178,8 +188,7 @@ impl<'a> LookAheadSelection<'a> {
178
188
. iter ( )
179
189
. map ( |p| LookAheadArgument :: new ( p, vars) )
180
190
. collect ( )
181
- } )
182
- . unwrap_or_else ( Vec :: new) ;
191
+ } ) . unwrap_or_else ( Vec :: new) ;
183
192
let mut ret = LookAheadSelection {
184
193
name,
185
194
alias,
@@ -256,18 +265,18 @@ impl<'a> LookAheadSelection<'a> {
256
265
}
257
266
258
267
/// Convert a eventually type independent selection into one for a concrete type
259
- pub fn for_explicit_type ( & self , type_name : & str ) -> ConcreteLookAheadSelection < ' a > {
268
+ pub fn for_explicit_type ( & self , type_name : & str ) -> ConcreteLookAheadSelection < ' a , S > {
260
269
ConcreteLookAheadSelection {
261
- children : self . children
270
+ children : self
271
+ . children
262
272
. iter ( )
263
273
. filter_map ( |c| match c. applies_for {
264
274
Applies :: OnlyType ( ref t) if * t == type_name => {
265
275
Some ( c. inner . for_explicit_type ( type_name) )
266
276
}
267
277
Applies :: All => Some ( c. inner . for_explicit_type ( type_name) ) ,
268
278
Applies :: OnlyType ( _) => None ,
269
- } )
270
- . collect ( ) ,
279
+ } ) . collect ( ) ,
271
280
name : self . name ,
272
281
alias : self . alias ,
273
282
arguments : self . arguments . clone ( ) ,
@@ -277,15 +286,15 @@ impl<'a> LookAheadSelection<'a> {
277
286
278
287
/// A selection performed by a query on a concrete type
279
288
#[ derive( Debug , PartialEq ) ]
280
- pub struct ConcreteLookAheadSelection < ' a > {
289
+ pub struct ConcreteLookAheadSelection < ' a , S : ' a > {
281
290
name : & ' a str ,
282
291
alias : Option < & ' a str > ,
283
- arguments : Vec < LookAheadArgument < ' a > > ,
284
- children : Vec < ConcreteLookAheadSelection < ' a > > ,
292
+ arguments : Vec < LookAheadArgument < ' a , S > > ,
293
+ children : Vec < ConcreteLookAheadSelection < ' a , S > > ,
285
294
}
286
295
287
296
/// A set of common methods for `ConcreteLookAheadSelection` and `LookAheadSelection`
288
- pub trait LookAheadMethods {
297
+ pub trait LookAheadMethods < S > {
289
298
/// Get the name of the field represented by the current selection
290
299
fn field_name ( & self ) -> & str ;
291
300
@@ -298,15 +307,15 @@ pub trait LookAheadMethods {
298
307
}
299
308
300
309
/// Get the top level arguments for the current selection
301
- fn arguments ( & self ) -> & [ LookAheadArgument ] ;
310
+ fn arguments ( & self ) -> & [ LookAheadArgument < S > ] ;
302
311
303
312
/// Get the top level argument with a given name from the current selection
304
- fn argument ( & self , name : & str ) -> Option < & LookAheadArgument > {
313
+ fn argument ( & self , name : & str ) -> Option < & LookAheadArgument < S > > {
305
314
self . arguments ( ) . iter ( ) . find ( |a| a. name == name)
306
315
}
307
316
}
308
317
309
- impl < ' a > LookAheadMethods for ConcreteLookAheadSelection < ' a > {
318
+ impl < ' a , S > LookAheadMethods < S > for ConcreteLookAheadSelection < ' a , S > {
310
319
fn field_name ( & self ) -> & str {
311
320
self . alias . unwrap_or ( self . name )
312
321
}
@@ -315,12 +324,12 @@ impl<'a> LookAheadMethods for ConcreteLookAheadSelection<'a> {
315
324
self . children . iter ( ) . find ( |c| c. name == name)
316
325
}
317
326
318
- fn arguments ( & self ) -> & [ LookAheadArgument ] {
327
+ fn arguments ( & self ) -> & [ LookAheadArgument < S > ] {
319
328
& self . arguments
320
329
}
321
330
}
322
331
323
- impl < ' a > LookAheadMethods for LookAheadSelection < ' a > {
332
+ impl < ' a , S > LookAheadMethods < S > for LookAheadSelection < ' a , S > {
324
333
fn field_name ( & self ) -> & str {
325
334
self . alias . unwrap_or ( self . name )
326
335
}
@@ -332,7 +341,7 @@ impl<'a> LookAheadMethods for LookAheadSelection<'a> {
332
341
. map ( |s| & s. inner )
333
342
}
334
343
335
- fn arguments ( & self ) -> & [ LookAheadArgument ] {
344
+ fn arguments ( & self ) -> & [ LookAheadArgument < S > ] {
336
345
& self . arguments
337
346
}
338
347
}
0 commit comments