1
- use std:: collections:: BTreeMap ;
1
+ use std:: { fmt , collections:: BTreeMap } ;
2
2
3
3
use combine:: { parser, ParseResult , Parser } ;
4
4
use combine:: easy:: Error ;
@@ -9,15 +9,29 @@ use tokenizer::{Kind as T, Token, TokenStream};
9
9
use helpers:: { punct, ident, kind, name} ;
10
10
use position:: Pos ;
11
11
12
+ /// Text abstracts over types that hold a string value.
13
+ /// It is used to make the AST generic over the string type.
14
+ pub trait Text < ' a > : ' a {
15
+ type Value : ' a + From < & ' a str > + AsRef < str > + std:: borrow:: Borrow < str > + PartialEq + Eq + PartialOrd + Ord + fmt:: Debug + Clone ;
16
+ }
17
+
18
+ impl < ' a > Text < ' a > for & ' a str {
19
+ type Value = Self ;
20
+ }
12
21
13
- /// An alias for string, used where graphql expects a name
14
- pub type Name = String ;
22
+ impl < ' a > Text < ' a > for String {
23
+ type Value = String ;
24
+ }
25
+
26
+ impl < ' a > Text < ' a > for std:: borrow:: Cow < ' a , str > {
27
+ type Value = Self ;
28
+ }
15
29
16
30
#[ derive( Debug , Clone , PartialEq ) ]
17
- pub struct Directive {
31
+ pub struct Directive < ' a , T : Text < ' a > > {
18
32
pub position : Pos ,
19
- pub name : Name ,
20
- pub arguments : Vec < ( Name , Value ) > ,
33
+ pub name : T :: Value ,
34
+ pub arguments : Vec < ( T :: Value , Value < ' a , T > ) > ,
21
35
}
22
36
23
37
/// This represents integer number
@@ -32,23 +46,23 @@ pub struct Directive {
32
46
pub struct Number ( pub ( crate ) i64 ) ;
33
47
34
48
#[ derive( Debug , Clone , PartialEq ) ]
35
- pub enum Value {
36
- Variable ( Name ) ,
49
+ pub enum Value < ' a , T : Text < ' a > > {
50
+ Variable ( T :: Value ) ,
37
51
Int ( Number ) ,
38
52
Float ( f64 ) ,
39
53
String ( String ) ,
40
54
Boolean ( bool ) ,
41
55
Null ,
42
- Enum ( Name ) ,
43
- List ( Vec < Value > ) ,
44
- Object ( BTreeMap < Name , Value > ) ,
56
+ Enum ( T :: Value ) ,
57
+ List ( Vec < Value < ' a , T > > ) ,
58
+ Object ( BTreeMap < T :: Value , Value < ' a , T > > ) ,
45
59
}
46
60
47
61
#[ derive( Debug , Clone , PartialEq ) ]
48
- pub enum Type {
49
- NamedType ( Name ) ,
50
- ListType ( Box < Type > ) ,
51
- NonNullType ( Box < Type > ) ,
62
+ pub enum Type < ' a , T : Text < ' a > > {
63
+ NamedType ( T :: Value ) ,
64
+ ListType ( Box < Type < ' a , T > > ) ,
65
+ NonNullType ( Box < Type < ' a , T > > ) ,
52
66
}
53
67
54
68
impl Number {
@@ -64,25 +78,27 @@ impl From<i32> for Number {
64
78
}
65
79
}
66
80
67
- pub fn directives < ' a > ( input : & mut TokenStream < ' a > )
68
- -> ParseResult < Vec < Directive > , TokenStream < ' a > >
81
+ pub fn directives < ' a , T > ( input : & mut TokenStream < ' a > )
82
+ -> ParseResult < Vec < Directive < ' a , T > > , TokenStream < ' a > >
83
+ where T : Text < ' a > ,
69
84
{
70
85
many ( position ( )
71
86
. skip ( punct ( "@" ) )
72
- . and ( name ( ) )
87
+ . and ( name :: < ' a , T > ( ) )
73
88
. and ( parser ( arguments) )
74
89
. map ( |( ( position, name) , arguments) | {
75
90
Directive { position, name, arguments }
76
91
} ) )
77
92
. parse_stream ( input)
78
93
}
79
94
80
- pub fn arguments < ' a > ( input : & mut TokenStream < ' a > )
81
- -> ParseResult < Vec < ( String , Value ) > , TokenStream < ' a > >
95
+ pub fn arguments < ' a , T > ( input : & mut TokenStream < ' a > )
96
+ -> ParseResult < Vec < ( T :: Value , Value < ' a , T > ) > , TokenStream < ' a > >
97
+ where T : Text < ' a > ,
82
98
{
83
99
optional (
84
100
punct ( "(" )
85
- . with ( many1 ( name ( )
101
+ . with ( many1 ( name :: < ' a , T > ( )
86
102
. skip ( punct ( ":" ) )
87
103
. and ( parser ( value) ) ) )
88
104
. skip ( punct ( ")" ) ) )
@@ -92,27 +108,29 @@ pub fn arguments<'a>(input: &mut TokenStream<'a>)
92
108
. parse_stream ( input)
93
109
}
94
110
95
- pub fn int_value < ' a > ( input : & mut TokenStream < ' a > )
96
- -> ParseResult < Value , TokenStream < ' a > >
111
+ pub fn int_value < ' a , S > ( input : & mut TokenStream < ' a > )
112
+ -> ParseResult < Value < ' a , S > , TokenStream < ' a > >
113
+ where S : Text < ' a >
97
114
{
98
115
kind ( T :: IntValue ) . and_then ( |tok| tok. value . parse ( ) )
99
116
. map ( Number ) . map ( Value :: Int )
100
117
. parse_stream ( input)
101
118
}
102
119
103
- pub fn float_value < ' a > ( input : & mut TokenStream < ' a > )
104
- -> ParseResult < Value , TokenStream < ' a > >
120
+ pub fn float_value < ' a , S > ( input : & mut TokenStream < ' a > )
121
+ -> ParseResult < Value < ' a , S > , TokenStream < ' a > >
122
+ where S : Text < ' a >
105
123
{
106
124
kind ( T :: FloatValue ) . and_then ( |tok| tok. value . parse ( ) )
107
125
. map ( Value :: Float )
108
126
. parse_stream ( input)
109
127
}
110
128
111
- fn unquote_block_string ( src : & str ) -> Result < String , Error < Token , Token > > {
129
+ fn unquote_block_string < ' a > ( src : & ' a str ) -> Result < String , Error < Token < ' a > , Token < ' a > > > {
112
130
debug_assert ! ( src. starts_with( "\" \" \" " ) && src. ends_with( "\" \" \" " ) ) ;
113
131
let indent = src[ 3 ..src. len ( ) -3 ] . lines ( ) . skip ( 1 )
114
132
. filter_map ( |line| {
115
- let trimmed = line. trim_left ( ) . len ( ) ;
133
+ let trimmed = line. trim_start ( ) . len ( ) ;
116
134
if trimmed > 0 {
117
135
Some ( line. len ( ) - trimmed)
118
136
} else {
@@ -144,7 +162,8 @@ fn unquote_block_string(src: &str) -> Result<String, Error<Token, Token>> {
144
162
Ok ( result)
145
163
}
146
164
147
- fn unquote_string ( s : & str ) -> Result < String , Error < Token , Token > > {
165
+ fn unquote_string < ' a > ( s : & ' a str ) -> Result < String , Error < Token , Token > >
166
+ {
148
167
let mut res = String :: with_capacity ( s. len ( ) ) ;
149
168
debug_assert ! ( s. starts_with( '"' ) && s. ends_with( '"' ) ) ;
150
169
let mut chars = s[ 1 ..s. len ( ) -1 ] . chars ( ) ;
@@ -183,67 +202,73 @@ pub fn string<'a>(input: &mut TokenStream<'a>)
183
202
) ) . parse_stream ( input)
184
203
}
185
204
186
- pub fn string_value < ' a > ( input : & mut TokenStream < ' a > )
187
- -> ParseResult < Value , TokenStream < ' a > >
205
+ pub fn string_value < ' a , S > ( input : & mut TokenStream < ' a > )
206
+ -> ParseResult < Value < ' a , S > , TokenStream < ' a > >
207
+ where S : Text < ' a > ,
188
208
{
189
209
kind ( T :: StringValue ) . and_then ( |tok| unquote_string ( tok. value ) )
190
210
. map ( Value :: String )
191
211
. parse_stream ( input)
192
212
}
193
213
194
- pub fn block_string_value < ' a > ( input : & mut TokenStream < ' a > )
195
- -> ParseResult < Value , TokenStream < ' a > >
214
+ pub fn block_string_value < ' a , S > ( input : & mut TokenStream < ' a > )
215
+ -> ParseResult < Value < ' a , S > , TokenStream < ' a > >
216
+ where S : Text < ' a > ,
196
217
{
197
218
kind ( T :: BlockString ) . and_then ( |tok| unquote_block_string ( tok. value ) )
198
219
. map ( Value :: String )
199
220
. parse_stream ( input)
200
221
}
201
222
202
- pub fn plain_value < ' a > ( input : & mut TokenStream < ' a > )
203
- -> ParseResult < Value , TokenStream < ' a > >
223
+ pub fn plain_value < ' a , T > ( input : & mut TokenStream < ' a > )
224
+ -> ParseResult < Value < ' a , T > , TokenStream < ' a > >
225
+ where T : Text < ' a > ,
204
226
{
205
227
ident ( "true" ) . map ( |_| Value :: Boolean ( true ) )
206
228
. or ( ident ( "false" ) . map ( |_| Value :: Boolean ( false ) ) )
207
229
. or ( ident ( "null" ) . map ( |_| Value :: Null ) )
208
- . or ( name ( ) . map ( Value :: Enum ) )
230
+ . or ( name :: < ' a , T > ( ) . map ( Value :: Enum ) )
209
231
. or ( parser ( int_value) )
210
232
. or ( parser ( float_value) )
211
233
. or ( parser ( string_value) )
212
234
. or ( parser ( block_string_value) )
213
235
. parse_stream ( input)
214
236
}
215
237
216
- pub fn value < ' a > ( input : & mut TokenStream < ' a > )
217
- -> ParseResult < Value , TokenStream < ' a > >
238
+ pub fn value < ' a , T > ( input : & mut TokenStream < ' a > )
239
+ -> ParseResult < Value < ' a , T > , TokenStream < ' a > >
240
+ where T : Text < ' a > ,
218
241
{
219
242
parser ( plain_value)
220
- . or ( punct ( "$" ) . with ( name ( ) ) . map ( Value :: Variable ) )
243
+ . or ( punct ( "$" ) . with ( name :: < ' a , T > ( ) ) . map ( Value :: Variable ) )
221
244
. or ( punct ( "[" ) . with ( many ( parser ( value) ) ) . skip ( punct ( "]" ) )
222
245
. map ( Value :: List ) )
223
246
. or ( punct ( "{" )
224
- . with ( many ( name ( ) . skip ( punct ( ":" ) ) . and ( parser ( value) ) ) )
247
+ . with ( many ( name :: < ' a , T > ( ) . skip ( punct ( ":" ) ) . and ( parser ( value) ) ) )
225
248
. skip ( punct ( "}" ) )
226
249
. map ( Value :: Object ) )
227
250
. parse_stream ( input)
228
251
}
229
252
230
- pub fn default_value < ' a > ( input : & mut TokenStream < ' a > )
231
- -> ParseResult < Value , TokenStream < ' a > >
253
+ pub fn default_value < ' a , T > ( input : & mut TokenStream < ' a > )
254
+ -> ParseResult < Value < ' a , T > , TokenStream < ' a > >
255
+ where T : Text < ' a > ,
232
256
{
233
257
parser ( plain_value)
234
258
. or ( punct ( "[" ) . with ( many ( parser ( default_value) ) ) . skip ( punct ( "]" ) )
235
259
. map ( Value :: List ) )
236
260
. or ( punct ( "{" )
237
- . with ( many ( name ( ) . skip ( punct ( ":" ) ) . and ( parser ( default_value) ) ) )
261
+ . with ( many ( name :: < ' a , T > ( ) . skip ( punct ( ":" ) ) . and ( parser ( default_value) ) ) )
238
262
. skip ( punct ( "}" ) )
239
263
. map ( Value :: Object ) )
240
264
. parse_stream ( input)
241
265
}
242
266
243
- pub fn parse_type < ' a > ( input : & mut TokenStream < ' a > )
244
- -> ParseResult < Type , TokenStream < ' a > >
267
+ pub fn parse_type < ' a , T > ( input : & mut TokenStream < ' a > )
268
+ -> ParseResult < Type < ' a , T > , TokenStream < ' a > >
269
+ where T : Text < ' a > ,
245
270
{
246
- name ( ) . map ( Type :: NamedType )
271
+ name :: < ' a , T > ( ) . map ( Type :: NamedType )
247
272
. or ( punct ( "[" )
248
273
. with ( parser ( parse_type) )
249
274
. skip ( punct ( "]" ) )
0 commit comments