@@ -2,7 +2,7 @@ use std::collections::HashMap;
2
2
3
3
use crate :: {
4
4
ast:: { Directive , Fragment , InputValue , Selection } ,
5
- parser:: Spanning ,
5
+ parser:: { Span , Spanning } ,
6
6
value:: ScalarValue ,
7
7
} ;
8
8
@@ -18,48 +18,71 @@ pub enum Applies<'a> {
18
18
OnlyType ( & ' a str ) ,
19
19
}
20
20
21
- /// A JSON-like value that can is used as argument in the query execution
21
+ /// Shortcut for a [`Spanning`] containing a borrowed [`Span`].
22
+ type BorrowedSpanning < ' a , T > = Spanning < T , & ' a Span > ;
23
+
24
+ /// JSON-like value that can be used as an argument in the query execution.
22
25
///
23
- /// In contrast to `InputValue` these values do only contain constants,
26
+ /// In contrast to an [ `InputValue`], these values do only contain constants,
24
27
/// meaning that variables are already resolved.
25
- #[ derive( Debug , Clone , PartialEq ) ]
28
+ #[ derive( Clone , Debug , PartialEq ) ]
26
29
#[ allow( missing_docs) ]
27
30
pub enum LookAheadValue < ' a , S : ' a > {
28
31
Null ,
29
32
Scalar ( & ' a S ) ,
30
33
Enum ( & ' a str ) ,
31
- List ( Vec < LookAheadValue < ' a , S > > ) ,
32
- Object ( Vec < ( & ' a str , LookAheadValue < ' a , S > ) > ) ,
34
+ List ( Vec < BorrowedSpanning < ' a , LookAheadValue < ' a , S > > > ) ,
35
+ Object (
36
+ Vec < (
37
+ BorrowedSpanning < ' a , & ' a str > ,
38
+ BorrowedSpanning < ' a , LookAheadValue < ' a , S > > ,
39
+ ) > ,
40
+ ) ,
33
41
}
34
42
35
43
impl < ' a , S > LookAheadValue < ' a , S >
36
44
where
37
45
S : ScalarValue ,
38
46
{
39
- fn from_input_value ( input_value : & ' a InputValue < S > , vars : & ' a Variables < S > ) -> Self {
40
- match * input_value {
41
- InputValue :: Null => LookAheadValue :: Null ,
42
- InputValue :: Scalar ( ref s) => LookAheadValue :: Scalar ( s) ,
43
- InputValue :: Enum ( ref e) => LookAheadValue :: Enum ( e) ,
44
- InputValue :: Variable ( ref name) => vars
45
- . get ( name)
46
- . map ( |v| Self :: from_input_value ( v, vars) )
47
- . unwrap_or ( LookAheadValue :: Null ) ,
48
- InputValue :: List ( ref l) => LookAheadValue :: List (
49
- l. iter ( )
50
- . map ( |i| LookAheadValue :: from_input_value ( & i. item , vars) )
51
- . collect ( ) ,
52
- ) ,
53
- InputValue :: Object ( ref o) => LookAheadValue :: Object (
54
- o. iter ( )
55
- . map ( |( n, i) | {
56
- (
57
- & n. item as & str ,
58
- LookAheadValue :: from_input_value ( & i. item , vars) ,
59
- )
47
+ fn from_input_value (
48
+ input_value : BorrowedSpanning < ' a , & ' a InputValue < S > > ,
49
+ vars : & ' a Variables < S > ,
50
+ ) -> BorrowedSpanning < ' a , Self > {
51
+ Spanning {
52
+ span : input_value. span ,
53
+ item : match input_value. item {
54
+ InputValue :: Null => Self :: Null ,
55
+ InputValue :: Scalar ( s) => Self :: Scalar ( s) ,
56
+ InputValue :: Enum ( e) => Self :: Enum ( e) ,
57
+ InputValue :: Variable ( name) => vars
58
+ . get ( name)
59
+ . map ( |item| {
60
+ let input_value = Spanning {
61
+ span : input_value. span ,
62
+ item,
63
+ } ;
64
+ Self :: from_input_value ( input_value, vars) . item
60
65
} )
61
- . collect ( ) ,
62
- ) ,
66
+ . unwrap_or ( Self :: Null ) ,
67
+ InputValue :: List ( l) => Self :: List (
68
+ l. iter ( )
69
+ . map ( |i| Self :: from_input_value ( i. as_ref ( ) , vars) )
70
+ . collect ( ) ,
71
+ ) ,
72
+ InputValue :: Object ( o) => Self :: Object (
73
+ o. iter ( )
74
+ . map ( |( n, i) | {
75
+ (
76
+ Spanning {
77
+ span : & n. span ,
78
+ item : n. item . as_str ( ) ,
79
+ } ,
80
+ Self :: from_input_value ( i. as_ref ( ) , vars) ,
81
+ )
82
+ } )
83
+ . collect ( ) ,
84
+ ) ,
85
+ } ,
63
86
}
64
87
}
65
88
}
68
91
#[ derive( Debug , Clone , PartialEq ) ]
69
92
pub struct LookAheadArgument < ' a , S : ' a > {
70
93
name : & ' a str ,
71
- value : LookAheadValue < ' a , S > ,
94
+ value : BorrowedSpanning < ' a , LookAheadValue < ' a , S > > ,
72
95
}
73
96
74
97
impl < ' a , S > LookAheadArgument < ' a , S >
81
104
) -> Self {
82
105
LookAheadArgument {
83
106
name : name. item ,
84
- value : LookAheadValue :: from_input_value ( & value. item , vars) ,
107
+ value : LookAheadValue :: from_input_value ( value. as_ref ( ) , vars) ,
85
108
}
86
109
}
87
110
@@ -92,7 +115,12 @@ where
92
115
93
116
/// The value of the argument
94
117
pub fn value ( & ' a self ) -> & LookAheadValue < ' a , S > {
95
- & self . value
118
+ & self . value . item
119
+ }
120
+
121
+ /// The input source span of the argument
122
+ pub fn span ( & self ) -> & Span {
123
+ self . value . span
96
124
}
97
125
}
98
126
@@ -145,7 +173,7 @@ where
145
173
. find ( |item| item. 0 . item == "if" )
146
174
. map ( |( _, v) | {
147
175
if let LookAheadValue :: Scalar ( s) =
148
- LookAheadValue :: from_input_value ( & v . item , vars)
176
+ LookAheadValue :: from_input_value ( v . as_ref ( ) , vars) . item
149
177
{
150
178
s. as_bool ( ) . unwrap_or ( false )
151
179
} else {
@@ -160,7 +188,7 @@ where
160
188
. find ( |item| item. 0 . item == "if" )
161
189
. map ( |( _, v) | {
162
190
if let LookAheadValue :: Scalar ( b) =
163
- LookAheadValue :: from_input_value ( & v . item , vars)
191
+ LookAheadValue :: from_input_value ( v . as_ref ( ) , vars) . item
164
192
{
165
193
b. as_bool ( ) . map ( :: std:: ops:: Not :: not) . unwrap_or ( false )
166
194
} else {
@@ -472,12 +500,12 @@ impl<'a, S> LookAheadMethods<'a, S> for LookAheadSelection<'a, S> {
472
500
473
501
#[ cfg( test) ]
474
502
mod tests {
475
- use std:: collections:: HashMap ;
503
+ use std:: { collections:: HashMap , ops :: Range } ;
476
504
477
505
use crate :: {
478
506
ast:: { Document , OwnedDocument } ,
479
507
graphql_vars,
480
- parser:: UnlocatedParseResult ,
508
+ parser:: { SourcePosition , UnlocatedParseResult } ,
481
509
schema:: model:: SchemaType ,
482
510
validation:: test_harness:: { MutationRoot , QueryRoot , SubscriptionRoot } ,
483
511
value:: { DefaultScalarValue , ScalarValue } ,
@@ -509,6 +537,13 @@ mod tests {
509
537
fragments
510
538
}
511
539
540
+ fn span ( range : Range < ( usize , usize , usize ) > ) -> Span {
541
+ Span {
542
+ start : SourcePosition :: new ( range. start . 0 , range. start . 1 , range. start . 2 ) ,
543
+ end : SourcePosition :: new ( range. end . 0 , range. end . 1 , range. end . 2 ) ,
544
+ }
545
+ }
546
+
512
547
#[ test]
513
548
fn check_simple_query ( ) {
514
549
let docs = parse_document_source :: < DefaultScalarValue > (
@@ -711,12 +746,17 @@ query Hero {
711
746
& fragments,
712
747
)
713
748
. unwrap ( ) ;
749
+ let span0 = span ( ( 32 , 2 , 18 ) ..( 38 , 2 , 24 ) ) ;
750
+ let span1 = span ( ( 77 , 4 , 24 ) ..( 81 , 4 , 28 ) ) ;
714
751
let expected = LookAheadSelection {
715
752
name : "hero" ,
716
753
alias : None ,
717
754
arguments : vec ! [ LookAheadArgument {
718
755
name: "episode" ,
719
- value: LookAheadValue :: Enum ( "EMPIRE" ) ,
756
+ value: Spanning {
757
+ item: LookAheadValue :: Enum ( "EMPIRE" ) ,
758
+ span: & span0,
759
+ } ,
720
760
} ] ,
721
761
applies_for : Applies :: All ,
722
762
children : vec ! [
@@ -732,7 +772,10 @@ query Hero {
732
772
alias: None ,
733
773
arguments: vec![ LookAheadArgument {
734
774
name: "uppercase" ,
735
- value: LookAheadValue :: Scalar ( & DefaultScalarValue :: Boolean ( true ) ) ,
775
+ value: Spanning {
776
+ item: LookAheadValue :: Scalar ( & DefaultScalarValue :: Boolean ( true ) ) ,
777
+ span: & span1,
778
+ } ,
736
779
} ] ,
737
780
children: Vec :: new( ) ,
738
781
applies_for: Applies :: All ,
@@ -768,12 +811,16 @@ query Hero($episode: Episode) {
768
811
& fragments,
769
812
)
770
813
. unwrap ( ) ;
814
+ let span0 = span ( ( 51 , 2 , 18 ) ..( 59 , 2 , 26 ) ) ;
771
815
let expected = LookAheadSelection {
772
816
name : "hero" ,
773
817
alias : None ,
774
818
arguments : vec ! [ LookAheadArgument {
775
819
name: "episode" ,
776
- value: LookAheadValue :: Enum ( "JEDI" ) ,
820
+ value: Spanning {
821
+ item: LookAheadValue :: Enum ( "JEDI" ) ,
822
+ span: & span0,
823
+ } ,
777
824
} ] ,
778
825
applies_for : Applies :: All ,
779
826
children : vec ! [
@@ -821,12 +868,16 @@ query Hero($episode: Episode) {
821
868
& fragments,
822
869
)
823
870
. unwrap ( ) ;
871
+ let span0 = span ( ( 51 , 2 , 18 ) ..( 59 , 2 , 26 ) ) ;
824
872
let expected = LookAheadSelection {
825
873
name : "hero" ,
826
874
alias : None ,
827
875
arguments : vec ! [ LookAheadArgument {
828
876
name: "episode" ,
829
- value: LookAheadValue :: Null ,
877
+ value: Spanning {
878
+ item: LookAheadValue :: Null ,
879
+ span: & span0,
880
+ } ,
830
881
} ] ,
831
882
applies_for : Applies :: All ,
832
883
children : vec ! [ LookAheadSelection {
@@ -1121,12 +1172,16 @@ fragment comparisonFields on Character {
1121
1172
& fragments,
1122
1173
)
1123
1174
. unwrap ( ) ;
1175
+ let span0 = span ( ( 85 , 2 , 11 ) ..( 88 , 2 , 14 ) ) ;
1124
1176
let expected = LookAheadSelection {
1125
1177
name : "hero" ,
1126
1178
alias : None ,
1127
1179
arguments : vec ! [ LookAheadArgument {
1128
1180
name: "id" ,
1129
- value: LookAheadValue :: Scalar ( & DefaultScalarValue :: Int ( 42 ) ) ,
1181
+ value: Spanning {
1182
+ item: LookAheadValue :: Scalar ( & DefaultScalarValue :: Int ( 42 ) ) ,
1183
+ span: & span0,
1184
+ } ,
1130
1185
} ] ,
1131
1186
applies_for : Applies :: All ,
1132
1187
children : vec ! [
0 commit comments