@@ -2,7 +2,7 @@ use std::collections::HashMap;
22
33use crate :: {
44 ast:: { Directive , Fragment , InputValue , Selection } ,
5- parser:: Spanning ,
5+ parser:: { Span , Spanning } ,
66 value:: ScalarValue ,
77} ;
88
@@ -18,48 +18,71 @@ pub enum Applies<'a> {
1818 OnlyType ( & ' a str ) ,
1919}
2020
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.
2225///
23- /// In contrast to `InputValue` these values do only contain constants,
26+ /// In contrast to an [ `InputValue`], these values do only contain constants,
2427/// meaning that variables are already resolved.
25- #[ derive( Debug , Clone , PartialEq ) ]
28+ #[ derive( Clone , Debug , PartialEq ) ]
2629#[ allow( missing_docs) ]
2730pub enum LookAheadValue < ' a , S : ' a > {
2831 Null ,
2932 Scalar ( & ' a S ) ,
3033 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+ ) ,
3341}
3442
3543impl < ' a , S > LookAheadValue < ' a , S >
3644where
3745 S : ScalarValue ,
3846{
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
6065 } )
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+ } ,
6386 }
6487 }
6588}
6891#[ derive( Debug , Clone , PartialEq ) ]
6992pub struct LookAheadArgument < ' a , S : ' a > {
7093 name : & ' a str ,
71- value : LookAheadValue < ' a , S > ,
94+ value : BorrowedSpanning < ' a , LookAheadValue < ' a , S > > ,
7295}
7396
7497impl < ' a , S > LookAheadArgument < ' a , S >
81104 ) -> Self {
82105 LookAheadArgument {
83106 name : name. item ,
84- value : LookAheadValue :: from_input_value ( & value. item , vars) ,
107+ value : LookAheadValue :: from_input_value ( value. as_ref ( ) , vars) ,
85108 }
86109 }
87110
@@ -92,7 +115,12 @@ where
92115
93116 /// The value of the argument
94117 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
96124 }
97125}
98126
@@ -145,7 +173,7 @@ where
145173 . find ( |item| item. 0 . item == "if" )
146174 . map ( |( _, v) | {
147175 if let LookAheadValue :: Scalar ( s) =
148- LookAheadValue :: from_input_value ( & v . item , vars)
176+ LookAheadValue :: from_input_value ( v . as_ref ( ) , vars) . item
149177 {
150178 s. as_bool ( ) . unwrap_or ( false )
151179 } else {
@@ -160,7 +188,7 @@ where
160188 . find ( |item| item. 0 . item == "if" )
161189 . map ( |( _, v) | {
162190 if let LookAheadValue :: Scalar ( b) =
163- LookAheadValue :: from_input_value ( & v . item , vars)
191+ LookAheadValue :: from_input_value ( v . as_ref ( ) , vars) . item
164192 {
165193 b. as_bool ( ) . map ( :: std:: ops:: Not :: not) . unwrap_or ( false )
166194 } else {
@@ -472,12 +500,12 @@ impl<'a, S> LookAheadMethods<'a, S> for LookAheadSelection<'a, S> {
472500
473501#[ cfg( test) ]
474502mod tests {
475- use std:: collections:: HashMap ;
503+ use std:: { collections:: HashMap , ops :: Range } ;
476504
477505 use crate :: {
478506 ast:: { Document , OwnedDocument } ,
479507 graphql_vars,
480- parser:: UnlocatedParseResult ,
508+ parser:: { SourcePosition , UnlocatedParseResult } ,
481509 schema:: model:: SchemaType ,
482510 validation:: test_harness:: { MutationRoot , QueryRoot , SubscriptionRoot } ,
483511 value:: { DefaultScalarValue , ScalarValue } ,
@@ -509,6 +537,13 @@ mod tests {
509537 fragments
510538 }
511539
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+
512547 #[ test]
513548 fn check_simple_query ( ) {
514549 let docs = parse_document_source :: < DefaultScalarValue > (
@@ -711,12 +746,17 @@ query Hero {
711746 & fragments,
712747 )
713748 . unwrap ( ) ;
749+ let span0 = span ( ( 32 , 2 , 18 ) ..( 38 , 2 , 24 ) ) ;
750+ let span1 = span ( ( 77 , 4 , 24 ) ..( 81 , 4 , 28 ) ) ;
714751 let expected = LookAheadSelection {
715752 name : "hero" ,
716753 alias : None ,
717754 arguments : vec ! [ LookAheadArgument {
718755 name: "episode" ,
719- value: LookAheadValue :: Enum ( "EMPIRE" ) ,
756+ value: Spanning {
757+ item: LookAheadValue :: Enum ( "EMPIRE" ) ,
758+ span: & span0,
759+ } ,
720760 } ] ,
721761 applies_for : Applies :: All ,
722762 children : vec ! [
@@ -732,7 +772,10 @@ query Hero {
732772 alias: None ,
733773 arguments: vec![ LookAheadArgument {
734774 name: "uppercase" ,
735- value: LookAheadValue :: Scalar ( & DefaultScalarValue :: Boolean ( true ) ) ,
775+ value: Spanning {
776+ item: LookAheadValue :: Scalar ( & DefaultScalarValue :: Boolean ( true ) ) ,
777+ span: & span1,
778+ } ,
736779 } ] ,
737780 children: Vec :: new( ) ,
738781 applies_for: Applies :: All ,
@@ -768,12 +811,16 @@ query Hero($episode: Episode) {
768811 & fragments,
769812 )
770813 . unwrap ( ) ;
814+ let span0 = span ( ( 51 , 2 , 18 ) ..( 59 , 2 , 26 ) ) ;
771815 let expected = LookAheadSelection {
772816 name : "hero" ,
773817 alias : None ,
774818 arguments : vec ! [ LookAheadArgument {
775819 name: "episode" ,
776- value: LookAheadValue :: Enum ( "JEDI" ) ,
820+ value: Spanning {
821+ item: LookAheadValue :: Enum ( "JEDI" ) ,
822+ span: & span0,
823+ } ,
777824 } ] ,
778825 applies_for : Applies :: All ,
779826 children : vec ! [
@@ -821,12 +868,16 @@ query Hero($episode: Episode) {
821868 & fragments,
822869 )
823870 . unwrap ( ) ;
871+ let span0 = span ( ( 51 , 2 , 18 ) ..( 59 , 2 , 26 ) ) ;
824872 let expected = LookAheadSelection {
825873 name : "hero" ,
826874 alias : None ,
827875 arguments : vec ! [ LookAheadArgument {
828876 name: "episode" ,
829- value: LookAheadValue :: Null ,
877+ value: Spanning {
878+ item: LookAheadValue :: Null ,
879+ span: & span0,
880+ } ,
830881 } ] ,
831882 applies_for : Applies :: All ,
832883 children : vec ! [ LookAheadSelection {
@@ -1121,12 +1172,16 @@ fragment comparisonFields on Character {
11211172 & fragments,
11221173 )
11231174 . unwrap ( ) ;
1175+ let span0 = span ( ( 85 , 2 , 11 ) ..( 88 , 2 , 14 ) ) ;
11241176 let expected = LookAheadSelection {
11251177 name : "hero" ,
11261178 alias : None ,
11271179 arguments : vec ! [ LookAheadArgument {
11281180 name: "id" ,
1129- value: LookAheadValue :: Scalar ( & DefaultScalarValue :: Int ( 42 ) ) ,
1181+ value: Spanning {
1182+ item: LookAheadValue :: Scalar ( & DefaultScalarValue :: Int ( 42 ) ) ,
1183+ span: & span0,
1184+ } ,
11301185 } ] ,
11311186 applies_for : Applies :: All ,
11321187 children : vec ! [
0 commit comments