0

I'm trying to implement a enum for range of numbers. For example:

enum DoSomething: Int, Codable {
    case one = 1
    case two = 2
    case three = 3
    case other = 4..100
}

But on this case I get this error:

Raw value for enum case must be a literal

Any of you knows how can I implement the enum for a range of numbers?

or how can fix this error.

I'll really appreciate your help.

user2924482
  • 8,380
  • 23
  • 89
  • 173
  • 2
    Enums are backed by a single `Int`. I suspect what you're looking for is just a regular old `init(from int: Int)` – Alexander Jun 29 '20 at 23:19
  • 1
    What is the use-case? Do you want to *store* the value (4...100)? Or do you just want to init your enum as `other` if the init value is >= 4? – pawello2222 Jun 29 '20 at 23:38
  • @pawello2222 can you post an example? – user2924482 Jun 29 '20 at 23:42
  • 1
    @user2924482 I'm just trying to understand what you're trying to achieve. If you provide some example of how do you plan to use your enum (and why a range is important) it'll be easier to help you. – pawello2222 Jun 29 '20 at 23:44

1 Answers1

0

I came up with something like this

enum rangeEnum: Codable {

    case oneToTen
    case elevenToTwenty
    case custom(ClosedRange<Int>)

    init(rawValue: ClosedRange<Int>) {
        if rawValue == 1...10 {
            self = .oneToTen
        } else if rawValue == 11...20 {
            self = .elevenToTwenty
        } else {
            self = .custom(rawValue)
        }
    }

    var rawValue: ClosedRange<Int> {
        switch self {
        case .oneToTen:
            return 1...10
        case .elevenToTwenty:
            return 11...20
        case .custom(let customRange):
            return customRange
        }
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let firstIndex = try values.decode(Int.self, forKey: .firstIndex)
        let lastIndex = try values.decode(Int.self, forKey: .lastIndex)
        
        self = rangeEnum(rawValue: firstIndex...lastIndex)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(self.rawValue.first!, forKey: .firstIndex)
        try container.encode(self.rawValue.last!, forKey: .lastIndex)
    }

    enum CodingKeys: String, CodingKey {
        case firstIndex = "firstIndex"
        case lastIndex = "lastIndex"
    }

}

You can modify the cases to your liking of course plus you can init with a custom value, too.

Example usage:

for i in rangeEnum.oneToTen.rawValue {
    print("Value of i: \(i)")
}
    
for i in rangeEnum.elevenToTwenty.rawValue {
    print("Value of i: \(i)")
}
    
for i in rangeEnum.custom(25...45).rawValue {
    print("Value of i: \(i)")
}
Tomo Norbert
  • 770
  • 4
  • 13