Hey all, hope this post makes sense. Long story short, I'm wanting to pass a enum as the concrete type for a generic parameter in a struct if it conforms to a specific protocol.
Here is a quick example of what I'm attempting to do.
//This defines a NetworkResult type. Data would be passed from Networking component.
protocol NetworkResult {
static func result(_ data: Data) -> Self
}
//The concrete type that implements the NetworkResult. The idea is this enum will grow to have several different Results available as the need grows.
enum ReturnResult: NetworkResult {
case result(_ data: Data)
}
//This protocol will be used to define the different results a specific type can receive.
protocol ExampleResult: NetworkResult { }
//Needed to satisfy the protocol return of the Concrete type RR in Example
extension ReturnResult: ExampleResult { }
//RR here is limited to just what is defined in its own protocol for this specific type. In this case, just NetworkResult, but in the future it could handle any kind of return value
struct Example<RR: ExampleResult> {
func handle(_ result: RR) {
switch result {
case let .result(data): <------- Returns compiler error
//Handle decoding of data for a variety of types.
}
}
}
let example = Example<ReturnResult>()
let testData = "Hello World!".data(using: .utf8)!
example.handle(.result(testData))
The above is a quick example of what I'm hoping to do. I can successfully receive the data sent from ReturnResult.result(data)
, but I don't have any way to actually switch on it or extract the data.
i.e. if I don't try and switch and do print(result)
, it will print result(12 bytes)
.
At a high level, I understand that WHY it's causing the error, because the compiler can't guarantee or see that it RR is an enum, since the only expectation is that the type includes NetworkResult
conformance. I'm hoping that there is some kind of way to achieve this.
Is there a way to use an enum in this situation? Is this possible to do in Swift? Any tips on how to achieve roughly the same thing?