skip to Main Content
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.

2

Answers


  1. 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()
    }
    
    Login or Signup to reply.
  2. 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" {
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search