Protocol with Encodable protocol

58 Views Asked by At

I have struct that has parameter with protocol type

protocol CheckoutOrder {}

struct CheckoutOrderEntity: Encodable {
    private enum CodingKeys: String, CodingKey {
        case amount
        case payment
    }
    
    let amount: Int
    let payment: CheckoutOrder
}

Also have 2 structs which implements protocol CheckoutOrder

struct ApplePayOrderEntity: Encodable {
    private enum CodingKeys: String, CodingKey {
        case token
    }
    
    let token: ApplePayTokenEntity
}

extension ApplePayOrderEntity: CheckoutOrder { }
struct CheckoutPaymentEntity: Encodable {
    private enum CodingKeys: String, CodingKey {
        case terminalName
        case shouldUseBalance
    }
    
    let shouldUseBalance: Bool
    let terminalName: String
}

extension CheckoutPaymentEntity: CheckoutOrder { }

I have an error: Type 'CheckoutOrderEntity' does not conform to protocol 'Encodable' and CheckoutOrder protocol requires function 'encode(to:)'.... So, the main reason of using protocol is that payment can be type of ApplePayOrderEntity or CheckoutPaymentEntity. How to solve problem or what is best practice in this case?

1

There are 1 best solutions below

0
Joakim Danielson On BEST ANSWER

First you need to make the protocol extend Encodable to tell the compiler that anything that conforms to CheckoutOrder also conforms to Encodable

protocol CheckoutOrder: Encodable {}

Then I would use generics for this and change CheckoutOrderEntity to

struct CheckoutOrderEntity<Payment: CheckoutOrder>: Encodable {
    private enum CodingKeys: String, CodingKey {
        case amount
        case payment
    }

    let amount: Int
    let payment: Payment
}

Example

let checkout = CheckoutOrderEntity(amount: 1000,
                                   payment: CheckoutPaymentEntity(shouldUseBalance: true,
                                                                  terminalName: "terminal"))