Toka
Toka

Reputation: 953

Multiple enum implementing protocols questions

I defined enums as confirming to a protocol Eventable:

protocol Eventable {
    var name: String { get }
    static var all: [Eventable] { get }
}

enum MyEnum: String, Eventable {
    case bla = "bla"
    case blu = "blu"

    var name: String {
        return self.rawValue
    }

    static var all: [Eventable] {
        return [
            MyEnum.bla,
            MyEnum.blu
        ]
    }
}

I have other enums like MyEnum also under the form: enum Bla: String, Eventable { }

I have two questions:

  1. for the enums having a String data type, I would like to avoid duplicating the generation of the variable name: var name: String I am not sure how to write that in Swift. I tried to play around with the "where" clause but not success. How can I achieve that?

  2. when I write my enums and conform to the protocol for that part: static var all: [Eventable] { get }. I would like that for the enum MyEnum, it constrains the variable to: static var all: [MyEnum] { ... } because for now I can put in the returned array any element being an Eventable and it's not what I need. Amongst other things, I tried to define a generic constraint in the protocol for it, but I get the following error:

Protocol 'Eventable' can only be used as a generic constraint because it has Self or associated type requirements

Thank you very much for the help!

Upvotes: 2

Views: 655

Answers (2)

zombie
zombie

Reputation: 5259

For the part of the question we need to extend Eventable protocol where Self inherits RawRepresentable

protocol Eventable {
    var name: String { get }
    static var all: [Self] { get }
}

extension Eventable where Self: RawRepresentable {
    var name: Self.RawValue {
        return self.rawValue
    }
}

enum MyEnum: String, Eventable {
    case bla = "bla"
    case blu = "blu"

    static var all: [MyEnum] = [bla, blu]
}

For the second part of your question we need to configure the function to handle a generic type

I would suggest making the function generic as well here is an example

func printEnum<T: Eventable>(_ event: T) {
    print(event.name)
}

and we can use it for any object confirms to Eventable

printEnum(MyEnum.bla)

Upvotes: 1

Sweeper
Sweeper

Reputation: 270890

For your second question, you just need to use Self:

protocol Eventable {
    var name: String { get }
    static var all: [Self] { get }
}

Self, similar to self, just means "the current type".

The first question is a little bit harder because you can't really get all the values of an enum safely. See here for more info. The closest I got was:

extension Eventable where Self: RawRepresentable, Self.RawValue == String {
    var name: String {
        return self.rawValue
    }
}

This means that you can omit the declaration of name in MyEnum, but not all.

Upvotes: 1

Related Questions