@@ -4,8 +4,9 @@ import OrderedCollections
4
4
/// Represents a scalar type in the schema.
5
5
///
6
6
/// It is **highly** recommended that you do not subclass this type.
7
- /// Instead, modify the encoding/decoding behavior through the `MapEncoder`/`MapDecoder` options available through
8
- /// `Coders` or a custom encoding/decoding on the `ScalarType` itself.
7
+ /// Encoding/decoding behavior can be modified through the `MapEncoder`/`MapDecoder` options available through
8
+ /// `Coders` or a custom encoding/decoding on the `ScalarType` itself. If you need very custom serialization controls,
9
+ /// you may provide your own serialize, parseValue, and parseLiteral implementations.
9
10
open class Scalar < Resolver, Context, ScalarType: Codable > : TypeComponent < Resolver , Context > {
10
11
// TODO: Change this no longer be an open class
11
12
@@ -14,22 +15,34 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
14
15
name: name,
15
16
description: description,
16
17
serialize: { value in
17
- guard let scalar = value as? ScalarType else {
18
- throw GraphQLError (
19
- message: " Serialize expected type \( ScalarType . self) but got \( type ( of: value) ) "
20
- )
18
+ if let serialize = self . serialize {
19
+ return try serialize ( value, coders)
20
+ } else {
21
+ guard let scalar = value as? ScalarType else {
22
+ throw GraphQLError (
23
+ message: " Serialize expected type \( ScalarType . self) but got \( type ( of: value) ) "
24
+ )
25
+ }
26
+
27
+ return try self . serialize ( scalar: scalar, encoder: coders. encoder)
21
28
}
22
-
23
- return try self . serialize ( scalar: scalar, encoder: coders. encoder)
24
29
} ,
25
30
parseValue: { map in
26
- let scalar = try self . parse ( map: map, decoder: coders. decoder)
27
- return try self . serialize ( scalar: scalar, encoder: coders. encoder)
31
+ if let parseValue = self . parseValue {
32
+ return try parseValue ( map, coders)
33
+ } else {
34
+ let scalar = try self . parse ( map: map, decoder: coders. decoder)
35
+ return try self . serialize ( scalar: scalar, encoder: coders. encoder)
36
+ }
28
37
} ,
29
38
parseLiteral: { value in
30
- let map = value. map
31
- let scalar = try self . parse ( map: map, decoder: coders. decoder)
32
- return try self . serialize ( scalar: scalar, encoder: coders. encoder)
39
+ if let parseLiteral = self . parseLiteral {
40
+ return try parseLiteral ( value, coders)
41
+ } else {
42
+ let map = value. map
43
+ let scalar = try self . parse ( map: map, decoder: coders. decoder)
44
+ return try self . serialize ( scalar: scalar, encoder: coders. encoder)
45
+ }
33
46
}
34
47
)
35
48
@@ -40,18 +53,30 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
40
53
try typeProvider. mapName ( ScalarType . self, to: name)
41
54
}
42
55
56
+ // TODO: Remove open func, instead relying on a passed closure
43
57
open func serialize( scalar: ScalarType , encoder: MapEncoder ) throws -> Map {
44
58
try encoder. encode ( scalar)
45
59
}
46
60
61
+ // TODO: Remove open func, instead relying on a passed closure
47
62
open func parse( map: Map , decoder: MapDecoder ) throws -> ScalarType {
48
63
try decoder. decode ( ScalarType . self, from: map)
49
64
}
50
65
66
+ let serialize : ( ( Any , Coders ) throws -> Map ) ?
67
+ let parseValue : ( ( Map , Coders ) throws -> Map ) ?
68
+ let parseLiteral : ( ( GraphQL . Value , Coders ) throws -> Map ) ?
69
+
51
70
init (
52
71
type _: ScalarType . Type ,
53
- name: String ?
72
+ name: String ? ,
73
+ serialize: ( ( Any , Coders ) throws -> Map ) ? = nil ,
74
+ parseValue: ( ( Map , Coders ) throws -> Map ) ? = nil ,
75
+ parseLiteral: ( ( GraphQL . Value , Coders ) throws -> Map ) ? = nil
54
76
) {
77
+ self . serialize = serialize
78
+ self . parseValue = parseValue
79
+ self . parseLiteral = parseLiteral
55
80
super. init (
56
81
name: name ?? Reflection . name ( for: ScalarType . self) ,
57
82
type: . scalar
@@ -62,11 +87,17 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
62
87
public extension Scalar {
63
88
convenience init (
64
89
_ type: ScalarType . Type ,
65
- as name: String ? = nil
90
+ as name: String ? = nil ,
91
+ serialize: ( ( Any , Coders ) throws -> Map ) ? = nil ,
92
+ parseValue: ( ( Map , Coders ) throws -> Map ) ? = nil ,
93
+ parseLiteral: ( ( GraphQL . Value , Coders ) throws -> Map ) ? = nil
66
94
) {
67
95
self . init (
68
96
type: type,
69
- name: name
97
+ name: name,
98
+ serialize: serialize,
99
+ parseValue: parseValue,
100
+ parseLiteral: parseLiteral
70
101
)
71
102
}
72
103
}
0 commit comments