@@ -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