@@ -4,8 +4,9 @@ import OrderedCollections
44/// Represents a scalar type in the schema.
55///
66/// 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.
910open class Scalar < Resolver, Context, ScalarType: Codable > : TypeComponent < Resolver , Context > {
1011 // TODO: Change this no longer be an open class
1112
@@ -14,22 +15,34 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
1415 name: name,
1516 description: description,
1617 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)
2128 }
22-
23- return try self . serialize ( scalar: scalar, encoder: coders. encoder)
2429 } ,
2530 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+ }
2837 } ,
2938 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+ }
3346 }
3447 )
3548
@@ -40,18 +53,30 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
4053 try typeProvider. mapName ( ScalarType . self, to: name)
4154 }
4255
56+ // TODO: Remove open func, instead relying on a passed closure
4357 open func serialize( scalar: ScalarType , encoder: MapEncoder ) throws -> Map {
4458 try encoder. encode ( scalar)
4559 }
4660
61+ // TODO: Remove open func, instead relying on a passed closure
4762 open func parse( map: Map , decoder: MapDecoder ) throws -> ScalarType {
4863 try decoder. decode ( ScalarType . self, from: map)
4964 }
5065
66+ let serialize : ( ( Any , Coders ) throws -> Map ) ?
67+ let parseValue : ( ( Map , Coders ) throws -> Map ) ?
68+ let parseLiteral : ( ( GraphQL . Value , Coders ) throws -> Map ) ?
69+
5170 init (
5271 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
5476 ) {
77+ self . serialize = serialize
78+ self . parseValue = parseValue
79+ self . parseLiteral = parseLiteral
5580 super. init (
5681 name: name ?? Reflection . name ( for: ScalarType . self) ,
5782 type: . scalar
@@ -62,11 +87,17 @@ open class Scalar<Resolver, Context, ScalarType: Codable>: TypeComponent<Resolve
6287public extension Scalar {
6388 convenience init (
6489 _ 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
6694 ) {
6795 self . init (
6896 type: type,
69- name: name
97+ name: name,
98+ serialize: serialize,
99+ parseValue: parseValue,
100+ parseLiteral: parseLiteral
70101 )
71102 }
72103}
0 commit comments