Search code examples
swiftserializationencodingenumscodable

Codable Bool enum in swift?


I need something like the following:

enum SomeEnum: Bool, Codable {
  case accept = true
  case reject = false
}

struct SomeStruct {
  var someEnum: SomeEnum
}

let s: SomeStruct = ...
print(try! try! JSONEncoder().encode(s)) //{"someEnum": true}

Problem 1: Bool type can't be simply applied to enums. Resolved here: Raw type 'Bool' is not expressible by any literal

Problem 2: Instead of {"someEnum": true} console log shows {"someEnum": {"true": {}} - unresolved. How to fix it correctly? Is it possible to solve by editing SomeEnum code only (because this enum may be used in other places).


Solution

  • So I tried your code with minimal fixes to pass the compilation... and it produces the output you expect. Fixes:

    // Fix 1: Follow advice from another SO thread to get Bool enum to conform to RawRepresentable
    extension Bool: ExpressibleByIntegerLiteral {
        public init(integerLiteral value: Int) {
            self = value != 0
        }
    }
    
    enum SomeEnum: Bool, Codable, RawRepresentable {
      case accept = true
      case reject = false
    }
    
    // Fix 2: Mark SomeStruct as Codable
    struct SomeStruct: Codable {
      var someEnum: SomeEnum
    }
    
    // Fix 3: Make example to be actually executable
    let s: SomeStruct = SomeStruct(someEnum: .accept)
    let encoded = try JSONEncoder().encode(s)
    print(String(data: encoded, encoding: .utf8)!)
    

    And the example prints out:

    {"someEnum":true}
    

    (This should be a comment really, as it doesn't solve anything, but won't fit in the comment)