Make Float80 Codable

I think the following is a viable implementation:

public extension LosslessStringConvertible where Self: Encodable {
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode("\(self)")
    }
}
public extension LosslessStringConvertible where Self: Decodable {
    init(from decoder: Decoder) throws {
        let stringRep = try decoder.singleValueContainer().decode(String.self)
        self.init(stringRep)!
    }
}

// Opt in.
extension Float80: Codable {}

// Test.
import Foundation

let f80 = Float80(3.142)
let encodedData = try JSONEncoder().encode(f80)
print(String(data: encodedData, encoding: .utf8)!)

let decodedF80 = try JSONDecoder().decode(Float80.self, from: encodedData)
print(decodedF80 == f80)

The difference is that you have to opt in. Therefore concerns about all LosslessStringConvertibles suddenly becoming Codable are mitigated and you can still do your own implementation if you wish.

Unfortunately I think there is a Codable bug, see Problem with Encoder.singleValueContainer, and so the above currently doesn't work :(.

1 Like