1
+ /**
2
+ * Maximum possible Int value as per GraphQL Spec (32-bit signed integer).
3
+ * n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe up-to 2^53 - 1
4
+ * */
5
+ let GRAPHQL_MAX_INT = 2_147_483_647
6
+
7
+ /**
8
+ * Minimum possible Int value as per GraphQL Spec (32-bit signed integer).
9
+ * n.b. This differs from JavaScript's numbers that are IEEE 754 doubles safe starting at -(2^53 - 1)
10
+ * */
11
+ let GRAPHQL_MIN_INT = - 2_147_483_648
12
+
1
13
public let GraphQLInt = try ! GraphQLScalarType (
2
14
name: " Int " ,
3
15
description:
4
16
" The `Int` scalar type represents non-fractional signed whole numeric " +
5
17
" values. Int can represent values between -(2^31) and 2^31 - 1. " ,
6
- serialize: { try map ( from: $0) } ,
7
- parseValue: { try . int( $0. intValue ( converting: true ) ) } ,
18
+ serialize: { outputValue in
19
+ if let value = outputValue as? Map {
20
+ if case let . number( value) = value {
21
+ return . int( value. intValue)
22
+ }
23
+ throw GraphQLError (
24
+ message: " Float cannot represent non numeric value: \( value) "
25
+ )
26
+ }
27
+ if let value = outputValue as? Bool {
28
+ return value ? . int( 1 ) : . int( 0 )
29
+ }
30
+ if let value = outputValue as? String , value != " " , let int = Int ( value) {
31
+ return . int( int)
32
+ }
33
+ if
34
+ let value = outputValue as? Double , Double ( GRAPHQL_MIN_INT) <= value,
35
+ value <= Double ( GRAPHQL_MAX_INT) , value. isFinite
36
+ {
37
+ return . int( Int ( value) )
38
+ }
39
+ if let value = outputValue as? Int , GRAPHQL_MIN_INT <= value, value <= GRAPHQL_MAX_INT {
40
+ return . int( value)
41
+ }
42
+ throw GraphQLError (
43
+ message: " Int cannot represent non-integer value: \( outputValue) "
44
+ )
45
+ } ,
46
+ parseValue: { inputValue in
47
+ if
48
+ case let . number( value) = inputValue, Double ( GRAPHQL_MIN_INT) <= value. doubleValue,
49
+ value. doubleValue <= Double ( GRAPHQL_MAX_INT) , value. doubleValue. isFinite
50
+ {
51
+ return . number( value)
52
+ }
53
+ throw GraphQLError (
54
+ message: " Int cannot represent non-integer value: \( inputValue) "
55
+ )
56
+ } ,
8
57
parseLiteral: { ast in
9
58
if let ast = ast as? IntValue , let int = Int ( ast. value) {
10
59
return . int( int)
@@ -23,8 +72,39 @@ public let GraphQLFloat = try! GraphQLScalarType(
23
72
" The `Float` scalar type represents signed double-precision fractional " +
24
73
" values as specified by " +
25
74
" [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point). " ,
26
- serialize: { try map ( from: $0) } ,
27
- parseValue: { try . double( $0. doubleValue ( converting: true ) ) } ,
75
+ serialize: { outputValue in
76
+ if let value = outputValue as? Map {
77
+ if case let . number( value) = value {
78
+ return . double( value. doubleValue)
79
+ }
80
+ throw GraphQLError (
81
+ message: " Float cannot represent non numeric value: \( value) "
82
+ )
83
+ }
84
+ if let value = outputValue as? Bool {
85
+ return value ? . double( 1 ) : . double( 0 )
86
+ }
87
+ if let value = outputValue as? String , value != " " , let double = Double ( value) {
88
+ return . double( double)
89
+ }
90
+ if let value = outputValue as? Double , value. isFinite {
91
+ return . double( value)
92
+ }
93
+ if let value = outputValue as? Int {
94
+ return . double( Double ( value) )
95
+ }
96
+ throw GraphQLError (
97
+ message: " Float cannot represent non numeric value: \( outputValue) "
98
+ )
99
+ } ,
100
+ parseValue: { inputValue in
101
+ if case let . number( value) = inputValue, value. doubleValue. isFinite {
102
+ return . number( value)
103
+ }
104
+ throw GraphQLError (
105
+ message: " Float cannot represent non numeric value: \( inputValue) "
106
+ )
107
+ } ,
28
108
parseLiteral: { ast in
29
109
if let ast = ast as? FloatValue , let double = Double ( ast. value) {
30
110
return . double( double)
@@ -47,8 +127,39 @@ public let GraphQLString = try! GraphQLScalarType(
47
127
" The `String` scalar type represents textual data, represented as UTF-8 " +
48
128
" character sequences. The String type is most often used by GraphQL to " +
49
129
" represent free-form human-readable text. " ,
50
- serialize: { try map ( from: $0) } ,
51
- parseValue: { try . string( $0. stringValue ( converting: true ) ) } ,
130
+ serialize: { outputValue in
131
+ if let value = outputValue as? Map {
132
+ if case let . string( value) = value {
133
+ return . string( value)
134
+ }
135
+ throw GraphQLError (
136
+ message: " String cannot represent a non string value: \( value) "
137
+ )
138
+ }
139
+ if let value = outputValue as? String {
140
+ return . string( value)
141
+ }
142
+ if let value = outputValue as? Bool {
143
+ return value ? . string( " true " ) : . string( " false " )
144
+ }
145
+ if let value = outputValue as? Int {
146
+ return . string( value. description)
147
+ }
148
+ if let value = outputValue as? Double , value. isFinite {
149
+ return . string( value. description)
150
+ }
151
+ throw GraphQLError (
152
+ message: " String cannot represent value: \( outputValue) "
153
+ )
154
+ } ,
155
+ parseValue: { outputValue in
156
+ if case let . string( value) = outputValue {
157
+ return . string( value)
158
+ }
159
+ throw GraphQLError (
160
+ message: " String cannot represent a non string value: \( outputValue) "
161
+ )
162
+ } ,
52
163
parseLiteral: { ast in
53
164
if let ast = ast as? StringValue {
54
165
return . string( ast. value)
@@ -64,8 +175,36 @@ public let GraphQLString = try! GraphQLScalarType(
64
175
public let GraphQLBoolean = try ! GraphQLScalarType (
65
176
name: " Boolean " ,
66
177
description: " The `Boolean` scalar type represents `true` or `false`. " ,
67
- serialize: { try map ( from: $0) } ,
68
- parseValue: { try . bool( $0. boolValue ( converting: true ) ) } ,
178
+ serialize: { outputValue in
179
+ if let value = outputValue as? Map {
180
+ if case let . bool( value) = value {
181
+ return . bool( value)
182
+ }
183
+ if case let . number( value) = value {
184
+ return . bool( value. intValue != 0 )
185
+ }
186
+ throw GraphQLError (
187
+ message: " Boolean cannot represent a non boolean value: \( value) "
188
+ )
189
+ }
190
+ if let value = outputValue as? Bool {
191
+ return . bool( value)
192
+ }
193
+ if let value = outputValue as? Int {
194
+ return . bool( value != 0 )
195
+ }
196
+ throw GraphQLError (
197
+ message: " Boolean cannot represent a non boolean value: \( outputValue) "
198
+ )
199
+ } ,
200
+ parseValue: { inputValue in
201
+ if case let . bool( value) = inputValue {
202
+ return inputValue
203
+ }
204
+ throw GraphQLError (
205
+ message: " Boolean cannot represent a non boolean value: \( inputValue) "
206
+ )
207
+ } ,
69
208
parseLiteral: { ast in
70
209
if let ast = ast as? BooleanValue {
71
210
return . bool( ast. value)
@@ -86,8 +225,35 @@ public let GraphQLID = try! GraphQLScalarType(
86
225
" response as a String; however, it is not intended to be human-readable. " +
87
226
" When expected as an input type, any string (such as ` \" 4 \" `) or integer " +
88
227
" (such as `4`) input value will be accepted as an ID. " ,
89
- serialize: { try map ( from: $0) } ,
90
- parseValue: { try . string( $0. stringValue ( converting: true ) ) } ,
228
+ serialize: { outputValue in
229
+ if let value = outputValue as? Map {
230
+ if case let . string( value) = value {
231
+ return . string( value)
232
+ }
233
+ if case let . number( value) = value {
234
+ return . string( value. description)
235
+ }
236
+ throw GraphQLError (
237
+ message: " ID cannot represent value: \( value) "
238
+ )
239
+ }
240
+ if let value = outputValue as? String {
241
+ return . string( value)
242
+ }
243
+ if let value = outputValue as? Int {
244
+ return . string( value. description)
245
+ }
246
+ throw GraphQLError ( message: " ID cannot represent value: \( outputValue) " )
247
+ } ,
248
+ parseValue: { inputValue in
249
+ if case let . string( value) = inputValue {
250
+ return inputValue
251
+ }
252
+ if case let . number( value) = inputValue, value. storageType == . int {
253
+ return . string( value. description)
254
+ }
255
+ throw GraphQLError ( message: " ID cannot represent value: \( inputValue) " )
256
+ } ,
91
257
parseLiteral: { ast in
92
258
if let ast = ast as? StringValue {
93
259
return . string( ast. value)
0 commit comments