Search code examples
swiftenumsprotocols

Adding a case to an existing enum with a protocol


I want to create a protocol that enforces a certain case on all enums conforming to this protocol.

For example, if I have a enum like this:

enum Foo{
    case bar(baz: String)
    case baz(bar: String)
}

I want to extend it with a protocol that adds another case:

case Fuzz(Int)

Is this possible?


Solution

  • Design

    The work around is to use a struct with static variables.

    Note: This is what is done in Swift 3 for Notification.Name

    Below is an implementation on Swift 3

    Struct:

    struct Car : RawRepresentable, Equatable, Hashable, Comparable {
    
        typealias RawValue = String
    
        var rawValue: String
    
        static let Red  = Car(rawValue: "Red")
        static let Blue = Car(rawValue: "Blue")
    
        //MARK: Hashable
    
        var hashValue: Int {
            return rawValue.hashValue
        }
    
        //MARK: Comparable
    
        public static func <(lhs: Car, rhs: Car) -> Bool {
    
            return lhs.rawValue < rhs.rawValue
        }
    
    }
    

    Protocol

    protocol CoolCar {
    
    }
    
    extension CoolCar {
    
        static var Yellow : Car {
    
            return Car(rawValue: "Yellow")
        }
    }
    
    extension Car : CoolCar {
    
    }
    

    Invoking

    let c1 = Car.Red
    
    
    switch c1 {
    case Car.Red:
        print("Car is red")
    case Car.Blue:
        print("Car is blue")
    case Car.Yellow:
        print("Car is yellow")
    default:
        print("Car is some other color")
    }
    
    if c1 == Car.Red {
        print("Equal")
    }
    
    if Car.Red > Car.Blue {
        print("Red is greater than Blue")
    }
    

    Note:

    Please note this approach is not a substitute for enum, use this only when the values are not known at compile time.