switch error {
case Project.Client.LoadError.operationFailed(let error2):
switch error2 {
case Project.Client.APIClientError.invalidStatusCode(let message, _):
guard message != nil, message == "error" else {
return refresh()
}
delegate?.error(invalidScript)
default:
refresh()
}
default:
refresh()
}
Here is my current code. This works but I feel there is a better way to do this.
How can I make error2
NOT go through another switch
statement and just cast it as an invalidStatusCode
that I can use?
Or, what terms can I search up to better understand what is happening here/understand what to look up myself for the answer? As I might not be fully understanding switch statements as casting type.
Thank you in advance.
CodePudding user response:
Pattern matching of enums with associated values is composable, so you can do this:
switch error {
case Project.Client.LoadError.operationFailed(Project.Client.APIClientError.invalidStatusCode("error" , _)):
delegate?.error(invalidScript)
default:
refresh()
}
You might notice that this is a bit hard to read because of how long these fully-qualified type-names are.
I suspect the type of error
is the general Error
, but in other cases, if the type of error
is already-known to be Project.Client.LoadError
, then you can just use .operationFailed
(leaving the type to be inferred from context). And if .operationFailed
's associated type is known to have type Project.Client.APIClientError
, you can just use .invalidStatusCode
.
If not, you can use some local type-aliases can help with that:
typealias LoadError = Project.Client.LoadError
typealias APIClientError = Project.Client.APIClientError
switch error {
case LoadError.operationFailed(APIClientError.invalidStatusCode("error", _)):
delegate?.error(invalidScript)
default:
refresh()
}
CodePudding user response:
Since you are just drilling down to one case for both switches, you don't need any switches at all. You can use if case
instead. To generalize, suppose we have this:
enum Outer {
case inner(Inner)
case other
}
enum Inner {
case message(String)
case other
}
Now suppose subject
might be an Outer. Then to determine that this is an Outer's .inner
case whose Inner value is .message
and that message's value is "howdy", we can say:
if case Outer.inner(let inner) = subject,
case Inner.message(let message) = inner,
message == "howdy" {