Skip to content

Latest commit

 

History

History
70 lines (55 loc) · 2.04 KB

Decode-Enums.md

File metadata and controls

70 lines (55 loc) · 2.04 KB

Decoding Enums

Decoding Structs and Classes is a similar process, but Enums can mix things up. If your Enum inherits from a Raw Type (String or Int), then making it conform to Decodable is as simple as pie. Let's look at a Role type enum:

enum Role: String {
  case User 
  case Admin
  case SuperAdmin
}

To make Role conform to Decodable, use this one line:

extension Role: Decodable { }

"THAT'S IT?! How?", you ask. Enums with a raw type like String or Int conform to RawRepresentable. Enums that are RawRepresentable are given a default value by the Swift compiler. With Int, the first case is 0 and each case is one more than the previous case. With String, the default raw value is the case name. So for Role, the raw value that represents the case User is "User". RawRepresentable enums also get a default initialize init(rawValue: ). We added a default implementation to Argo for Int and String enums so decoding can be this simple.

So, what if the enum doesn't have a raw type? Conforming to Decodable is a bit more involved but not too hard. Let's look at an example:

enum FootRace {
  case HalfMarathon
  case Marathon
  case UltraMarathon
}

We can write Decodable for FootRace like so:

extension FootRace: Decodable {
  static func decode(j: JSON) -> Decoded<FootRace> {
    switch j {

    // First, make sure JSON is a number.
    case let .Number(distance):

      // Next, match the number to the enum case.
      switch distance {

      // When a case matches, use pure to wrap the enum in Decoded.
      case 13.1: return pure(.HalfMarathon)
      case 26.2: return pure(.Marathon)
      case _ where distance > 26.2: return pure(.UltraMarathon)

      // Return an error if no case matched
      default: return .typeMismatch("marathon distance", actual: distance)
      }

    // Return an error if JSON is not a number.
    default: return .typeMismatch("Number", actual: j)
    }
  }
}