Hi. I've met weird behavior trying to encode URL and Decimal values as existentials. When instances of these types are wrapped as any Encodable
the result JSON string is incorrect.
Here is the minimal code for playground to reproduce:
let url = URL(string: "www.apple.com")!
let decimal = Decimal(string: "10.1")!
let urlJsonString: String // ok, == "www.apple.com"
let decimalJsonString: String // ok, == "10.1"
do {
let encoder = JSONEncoder()
let urlData = try! encoder.encode(url)
let decimalData = try! encoder.encode(decimal)
urlJsonString = String(decoding: urlData, as: UTF8.self)
decimalJsonString = String(decoding: decimalData, as: UTF8.self)
}
let urlJsonStringAny: String // invalid, == "{"relative":"www.apple.com"}"
let decimalJsonStringAny: String // invalid, == "{"exponent":-1,"length":1,"isCompact":true,"isNegative":false,"mantissa":[101,0,0,0,0,0,0,0]}"
do {
let encoder = JSONEncoder()
let urlData = try! encoder.encode(AnyEncodable(url as any Encodable))
let decimalData = try! encoder.encode(AnyEncodable(decimal as any Encodable))
urlJsonStringAny = String(decoding: urlData, as: UTF8.self)
decimalJsonStringAny = String(decoding: decimalData, as: UTF8.self)
}
public struct AnyEncodable: Encodable {
private let encodable: any Encodable
public init(_ encodable: any Encodable) {
self.encodable = encodable
}
public func encode(to encoder: any Encoder) throws {
try encodable.encode(to: encoder)
}
}
Existential values give "{"relative":"www.apple.com"}" for url instance and "{"exponent":-1,"length":1,"isCompact":true,"isNegative":false,"mantissa":[101,0,0,0,0,0,0,0]}" for decimal instance.
Seems it is a bug, but may be I'm missing something.