BinaryCoder icon indicating copy to clipboard operation
BinaryCoder copied to clipboard

Compile errors with swift 4.1

Open dandoen opened this issue 6 years ago • 1 comments

@mikeash getting the following compile errors building this project.

Swift Compiler Error Group
BinaryCodableExtensions.swift:6:1: Type 'Element' does not conform to protocol 'Decodable'
BinaryCodableExtensions.swift:6:1: 'BinaryDecodable' requires that 'Element' conform to 'Decodable'
BinaryCodableExtensions.swift:6:1: Requirement specified as 'Element' : 'Decodable'
BinaryCodableExtensions.swift:6:1: Requirement from conditional conformance of 'Array<Element>' to 'Decodable'
BinaryCodableExtensions.swift:6:1: Type 'Element' does not conform to protocol 'Encodable'
BinaryCodableExtensions.swift:6:1: 'BinaryEncodable' requires that 'Element' conform to 'Encodable'
BinaryCodableExtensions.swift:6:1: Requirement specified as 'Element' : 'Encodable'
BinaryCodableExtensions.swift:6:1: Requirement from conditional conformance of 'Array<Element>' to 'Encodable'

I'm not too familiar with Swift's new conditional conformance but attempted to fix these in BinaryCodableExtensions.swift. See:

Click to expand `BinaryCodableExtensions.swift`
/// Implementations of BinaryCodable for built-in types.

import Foundation


// AB: addition
extension Dictionary: BinaryCodable where Key: BinaryCodable, Value: BinaryCodable {
    public func binaryEncode(to encoder: BinaryEncoder) throws {

        try encoder.encode(self.count)
        for pair in self {
            try pair.key.encode(to: encoder)
            try pair.value.encode(to: encoder)
        }
    }
    
    public init(fromBinary decoder: BinaryDecoder) throws {
        let binaryKeyElement = Key.self
        let binaryValueElement = Value.self
        
        let count = try decoder.decode(Int.self)
        self.init()
        self.reserveCapacity(count)
        for _ in 0 ..< count {
            let decodedKey = try binaryKeyElement.init(from: decoder)
            let decodedValue = try binaryValueElement.init(from: decoder)
            self[decodedKey] = decodedValue
        }
    }
}

extension Array: BinaryCodable where Element: BinaryCodable {
    public func binaryEncode(to encoder: BinaryEncoder) throws {
        try encoder.encode(self.count)
        for element in self {
            try element.encode(to: encoder)
        }
    }
    
    public init(fromBinary decoder: BinaryDecoder) throws {
        let binaryElement = Element.self
        
        let count = try decoder.decode(Int.self)
        self.init()
        self.reserveCapacity(count)
        for _ in 0 ..< count {
            let decoded = try binaryElement.init(from: decoder)
            self.append(decoded)
        }
    }
}

extension String: BinaryCodable {
    public func binaryEncode(to encoder: BinaryEncoder) throws {
        try (Array(self.utf8) as! BinaryCodable).binaryEncode(to: encoder)
    }
    
    public init(fromBinary decoder: BinaryDecoder) throws {
        let utf8: [UInt8] = try (Array as [BinaryCodable.Type]).init(fromBinary: decoder) as! [UInt8]
        if let str = String(bytes: utf8, encoding: .utf8) {
            self = str
        } else {
            throw BinaryDecoder.Error.invalidUTF8(utf8)
        }
    }
}

But running into:

Cannot convert value of type 'Array<_>.Type' to type '[BinaryCodable.Type]' (aka 'Array<(BinaryDecodable & BinaryEncodable).Type>') in coercion

for this line

let utf8: [UInt8] = try (Array as [BinaryCodable.Type]).init(fromBinary: decoder) as! [UInt8]

Any suggestions?

dandoen avatar Aug 18 '18 21:08 dandoen

Have a look at my pull request. That should fix you issues with swift 4.1, if you haven't mannaged to solve them yourself by now.

m-rimestad avatar Aug 23 '18 13:08 m-rimestad