Skip to content

Commit ec37bdf

Browse files
Add fast-path for ConstructibleFromJSValue.Type
1 parent 59e7b65 commit ec37bdf

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

Sources/JavaScriptKit/JSValueDecoder.swift

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@ private struct _KeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContainerPr
118118
}
119119

120120
func decode<T>(_: T.Type, forKey key: Key) throws -> T where T: Decodable {
121-
return try T(from: _decoder(forKey: key))
121+
let jsValue = try _decode(forKey: key)
122+
if let jsType = T.self as? ConstructibleFromJSValue.Type {
123+
let maybeValue = jsType.construct(from: jsValue)
124+
if let value = maybeValue { return value as! T }
125+
}
126+
return try T(from: _decoder(forKey: key, value: jsValue))
122127
}
123128

124129
func nestedContainer<NestedKey>(keyedBy _: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey {
@@ -139,6 +144,10 @@ private struct _KeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContainerPr
139144

140145
func _decoder(forKey key: CodingKey) throws -> Decoder {
141146
let value = try _decode(forKey: key)
147+
return _decoder(forKey: key, value: value)
148+
}
149+
150+
func _decoder(forKey key: CodingKey, value: JSValue) -> Decoder {
142151
return decoder.decoder(referencing: value, with: key)
143152
}
144153
}
@@ -182,7 +191,12 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer {
182191
}
183192

184193
mutating func decode<T>(_: T.Type) throws -> T where T: Decodable {
185-
return try T(from: _decoder())
194+
let jsValue = _currentValue()
195+
if let jsType = T.self as? ConstructibleFromJSValue.Type {
196+
let maybeValue = jsType.construct(from: jsValue)
197+
if let value = maybeValue { return value as! T }
198+
}
199+
return try T(from: _decoder(value: jsValue))
186200
}
187201

188202
mutating func nestedContainer<NestedKey>(keyedBy _: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey {
@@ -198,7 +212,11 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer {
198212
}
199213

200214
mutating func _decoder() -> Decoder {
201-
decoder.decoder(referencing: _currentValue(), with: currentKey)
215+
_decoder(value: _currentValue())
216+
}
217+
218+
func _decoder(value: JSValue) -> Decoder {
219+
decoder.decoder(referencing: value, with: currentKey)
202220
}
203221
}
204222

0 commit comments

Comments
 (0)