-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Previous ID | SR-6112 |
Radar | None |
Original Reporter | brendanm500henderson (JIRA User) |
Type | Bug |
Status | Closed |
Resolution | Duplicate |
Environment
Swift 4
Xcode 9.6 beta
Mac OSX
Additional Detail from JIRA
Votes | 0 |
Component/s | Standard Library |
Labels | Bug, Codable |
Assignee | None |
Priority | Medium |
md5: 517a5763d90fe8049146529badff5abd
duplicates:
- SR-5206 [Codable] The encoded results of
Optional<URL>
are different betweenContainer.encode (_: ...)
andContainer.encodeIfPresent (_: ...)
.
Issue Description:
Arrays and Dictionaries do not call encode on the container protocols and then encodes the values as their underlying encode type.
example 1:
let value = URL(string: "test.com")
try! [value].encode(to: TestEncoder())
// call stack (a url value never gets encoded)
_Encoder unkeyedContainer()
_UnkeyedEncodingContainer superEncoder()
_Encoder singleValueContainer()
_Encoder singleValueContainer()
_Encoder container(keyedBy: ) (CodingKeys in _FB6C8C127CB51A72D58E049FC6F7743F)
_KeyedEncodingContainerProtocol encode(:forKey: ) String test.com relative
example 2:
let value = Date()
try! [1: value].encode(to: TestEncoder())
// call stack (a date value never gets encoded)
_Encoder container(keyedBy: ) _DictionaryCodingKey
_KeyedEncodingContainerProtocol<_DictionaryCodingKey> superEncoder(forKey: ) _DictionaryCodingKey(stringValue: "1", intValue: Optional(1))
_Encoder singleValueContainer()
_Encoder encode Double 529368384.419609
Is there a way to get around this? Like in the JSONEncoder at: https://github.com/apple/swift/blob/1457e4da9ddc55321648a4b602e9f5cdad857797/stdlib/public/SDK/Foundation/JSONEncoder.swift#L1774 line 667 in box_
// code used for testing
class _Encoder: Encoder, SingleValueEncodingContainer {
var codingPath: \[CodingKey\] = \[\]
var userInfo: \[CodingUserInfoKey : Any\] = \[:\]
func encodeNil() throws {fatalError()}
func encode(\_ value: Bool) throws {fatalError()}
func encode(\_ value: Int) throws {fatalError()}
func encode(\_ value: Int8) throws {fatalError()}
func encode(\_ value: Int16) throws {fatalError()}
func encode(\_ value: Int32) throws {fatalError()}
func encode(\_ value: Int64) throws {fatalError()}
func encode(\_ value: UInt) throws {fatalError()}
func encode(\_ value: UInt8) throws {fatalError()}
func encode(\_ value: UInt16) throws {fatalError()}
func encode(\_ value: UInt32) throws {fatalError()}
func encode(\_ value: UInt64) throws {fatalError()}
func encode(\_ value: Float) throws {fatalError()}
// Date stops here.
func encode(\_ value: Double) throws {
fatalError()
print(type(of: self), \#function, type(of: value), value)
}
func encode(\_ value: String) throws {fatalError()}
func encode\<T\>(\_ value: T) throws where T : Encodable {fatalError()}
func container\<Key\>(keyedBy type: Key.Type) -\> KeyedEncodingContainer\<Key\> where Key : CodingKey {
print(Swift.type(of: self), \#function, Key.self)
return KeyedEncodingContainer(\_KeyedEncodingContainerProtocol\<Key\>())
}
func unkeyedContainer() -\> UnkeyedEncodingContainer {
print(type(of: self), \#function)
return \_UnkeyedEncodingContainer()
}
func singleValueContainer() -\> SingleValueEncodingContainer {
print(type(of: self), \#function)
return self
}
}
struct _UnkeyedEncodingContainer: UnkeyedEncodingContainer {
var codingPath: \[CodingKey\] = \[\]
var count: Int = 0
mutating func encode(\_ value: Int) throws {fatalError()}
mutating func encode(\_ value: Int8) throws {fatalError()}
mutating func encode(\_ value: Int16) throws {fatalError()}
mutating func encode(\_ value: Int32) throws {fatalError()}
mutating func encode(\_ value: Int64) throws {fatalError()}
mutating func encode(\_ value: UInt) throws {fatalError()}
mutating func encode(\_ value: UInt8) throws {fatalError()}
mutating func encode(\_ value: UInt16) throws {fatalError()}
mutating func encode(\_ value: UInt32) throws {fatalError()}
mutating func encode(\_ value: UInt64) throws {fatalError()}
mutating func encode(\_ value: Float) throws {fatalError()}
mutating func encode(\_ value: Double) throws {fatalError()}
mutating func encode(\_ value: String) throws {fatalError()}
mutating func encode\<T\>(\_ value: T) throws where T : Encodable {fatalError()}
mutating func encode(\_ value: Bool) throws {fatalError()}
mutating func encodeNil() throws {fatalError()}
mutating func nestedContainer\<NestedKey\>(keyedBy keyType: NestedKey.Type) -\> KeyedEncodingContainer\<NestedKey\> where NestedKey : CodingKey {
fatalError()}
mutating func nestedUnkeyedContainer() -\> UnkeyedEncodingContainer {
fatalError()}
mutating func superEncoder() -\> Encoder {
print(type(of: self), \#function)
return \_Encoder()
}
}
struct _KeyedEncodingContainerProtocol<K: CodingKey>: KeyedEncodingContainerProtocol {
typealias Key = K
var codingPath: \[CodingKey\] = \[\]
mutating func encodeNil(forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Bool, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Int, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Int8, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Int16, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Int32, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Int64, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: UInt, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: UInt8, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: UInt16, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: UInt32, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: UInt64, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Float, forKey key: K) throws {fatalError()}
mutating func encode(\_ value: Double, forKey key: K) throws {fatalError()}
// URL stops here
mutating func encode(\_ value: String, forKey key: K) throws {
print(type(of: self), \#function, type(of: value), value, key)
}
mutating func encode\<T\>(\_ value: T, forKey key: K) throws where T : Encodable {fatalError()}
mutating func nestedContainer\<NestedKey\>(keyedBy keyType: NestedKey.Type, forKey key: K) -\> KeyedEncodingContainer\<NestedKey\> where NestedKey : CodingKey {
fatalError()}
mutating func nestedUnkeyedContainer(forKey key: K) -\> UnkeyedEncodingContainer {
fatalError()}
mutating func superEncoder() -\> Encoder {
fatalError()}
mutating func superEncoder(forKey key: K) -\> Encoder {
print(type(of: self), \#function, key)
return \_Encoder()
}
}
}