Matching multiple patterns in switch statement

I have the following types (slightly simplified):


enum BlockType {
  case Header
  case Text
  case ...
}

enum ScanState {
  case EmptyLine
  case Block(type: BlockType)
}


In one of my methods, I switch on ScanState:


switch scanState {
case .EmptyLine:
  ...

case .Block(let type) where type == .Header:
  ...

case .Block(let type) where type == .Text:
  ...
}


This works fine. However, now I change the BlockType enum to:


enum BlockType {
  case Header(level: Int)  // now has associated value
  case Text
  case ...
}


That causes the following line to fail compiling:


case .Block(let type) where type == .Header:
  ...


That makes sense because .Header is now an enum with an associated value and you can't use == to compare those.


Ideally, I'd extract the level value from the .Header case here too, something like this:


  case .Block(let type) where case .Header(let level) = type:
  ...


That also doesn't work. This appears to be unsupported syntax. However, the following works fine:


if case .Block(let type) = scanState, case .Header(let level) = type {
  ...
}


The `case .Header(let level) = type` construct works behind an `if` but not behind `where`.


Is there a way to express what I want in a single line?


If not, I can always nest another switch statement as follows, but I don't think that's as expressive:


switch scanState {
  case .EmptyLine:
  ...
  case .Block(let type):
      switch type {
      case .Header(let level):
        ...
      case .Text:
        ...
      }
} 


Thanks!

Accepted Reply

This seems to work:

var scanState: ScanState = .Block(type: .Header(level: 123))
switch scanState {
case .EmptyLine:
    print("Empty")
   
case .Block(.Header(let level)):
    print(level)
   
case .Block(.Text):
    print("Text")
}//->123

Replies

This seems to work:

var scanState: ScanState = .Block(type: .Header(level: 123))
switch scanState {
case .EmptyLine:
    print("Empty")
   
case .Block(.Header(let level)):
    print(level)
   
case .Block(.Text):
    print("Text")
}//->123

Hey, that's probably the one variation I didn't try. Thanks! :-)