Skip to content

Commit a83766b

Browse files
Merge pull request #187 from NeedleInAJayStack/feat/mutable-scalar-parsing
feat: Allows mutating scalar parse and serialization
2 parents 28257ca + 7790727 commit a83766b

1 file changed

Lines changed: 33 additions & 7 deletions

File tree

‎Sources/GraphQL/Type/Definition.swift‎

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,37 @@ extension GraphQLNonNull: GraphQLWrapperType {}
135135
/// try $0.map.asBool(converting: true)
136136
/// }
137137
/// )
138-
public final class GraphQLScalarType: Sendable {
138+
public final class GraphQLScalarType: @unchecked Sendable {
139139
public let name: String
140140
public let description: String?
141141
public let specifiedByURL: String?
142142
public let astNode: ScalarTypeDefinition?
143143
public let extensionASTNodes: [ScalarExtensionDefinition]
144144
public let kind: TypeKind = .scalar
145145

146-
let serialize: @Sendable (Any) throws -> Map
147-
let parseValue: @Sendable (Map) throws -> Map
148-
let parseLiteral: @Sendable (Value) throws -> Map
146+
/// The serialization of scalar values. This may be mutated during setup, but should not be
147+
/// modified once the schema is being used for execution.
148+
public var serialize: @Sendable (Any) throws -> Map {
149+
get { scalarPropertyQueue.sync { _serialize } }
150+
set { scalarPropertyQueue.sync(flags: .barrier) { _serialize = newValue } }
151+
}
152+
private var _serialize: @Sendable (Any) throws -> Map
153+
154+
/// The parsing of scalar values from the provided JSON Map. This may be mutated during setup, but should not be
155+
/// modified once the schema is being used for execution.
156+
public var parseValue: @Sendable (Map) throws -> Map {
157+
get { scalarPropertyQueue.sync { _parseValue } }
158+
set { scalarPropertyQueue.sync(flags: .barrier) { _parseValue = newValue } }
159+
}
160+
private var _parseValue: @Sendable (Map) throws -> Map
161+
162+
/// The parsing of scalar values from the provided Value literal. This may be mutated during setup, but should not be
163+
/// modified once the schema is being used for execution.
164+
public var parseLiteral: @Sendable (Value) throws -> Map {
165+
get { scalarPropertyQueue.sync { _parseLiteral } }
166+
set { scalarPropertyQueue.sync(flags: .barrier) { _parseLiteral = newValue } }
167+
}
168+
private var _parseLiteral: @Sendable (Value) throws -> Map
149169

150170
public init(
151171
name: String,
@@ -163,9 +183,9 @@ public final class GraphQLScalarType: Sendable {
163183
self.specifiedByURL = specifiedByURL
164184
self.astNode = astNode
165185
self.extensionASTNodes = extensionASTNodes
166-
self.serialize = serialize
167-
self.parseValue = parseValue ?? defaultParseValue
168-
self.parseLiteral = parseLiteral ?? defaultParseLiteral
186+
_serialize = serialize
187+
_parseValue = parseValue ?? defaultParseValue
188+
_parseLiteral = parseLiteral ?? defaultParseLiteral
169189
}
170190

171191
/// Serializes an internal value to include in a response.
@@ -1421,3 +1441,9 @@ private let fieldPropertyQueue = DispatchQueue(
14211441
label: "graphql.field.properties",
14221442
attributes: .concurrent
14231443
)
1444+
1445+
/// Shared reader/writer queue for scalar callbacks.
1446+
private let scalarPropertyQueue = DispatchQueue(
1447+
label: "graphql.scalar.properties",
1448+
attributes: .concurrent
1449+
)

0 commit comments

Comments
 (0)