Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a CustomStringConvertible description from this enum?

Tags:

enums

swift

I have the following enum

enum Properties: CustomStringConvertible {
    case binaryOperation(BinaryOperationProperties),
    brackets(BracketsProperties),
    chemicalElement(ChemicalElementProperties),
    differential(DifferentialProperties),
    function(FunctionProperties),
    number(NumberProperties),
    particle(ParticleProperties),
    relation(RelationProperties),
    stateSymbol(StateSymbolProperties),
    symbol(SymbolProperties)
}

and the structs all look like this

struct BinaryOperationProperties: Decodable, CustomStringConvertible {
    let operation: String
    var description: String { return operation }
}

So how do I make that enum conform to CustomStringConvertible? I tried with a simple getter but obviously that calls itself and I'd like to call the specific struct's instead.

Bonus points: does an enum defined like that have a name?

like image 964
Morpheu5 Avatar asked Oct 11 '17 15:10

Morpheu5


1 Answers

Such an enum is called enum with associated values.

I'd implement description by manually switching over the cases:

extension Properties: CustomStringConvertible {
    var description: String {
        switch self {
        case .binaryOperation(let props):
            return "binaryOperation(\(props))"
        case .brackets(let props):
            return "brackets(\(props))"
        ...
        }
    }
}

Edit: an alternative is to use Swift's Mirror reflection API. The enum case of an instance is listed as the mirror's child and you can print its label and value like this:

extension Properties: CustomStringConvertible {
    var description: String {
        let mirror = Mirror(reflecting: self)
        var result = ""
        for child in mirror.children {
            if let label = child.label {
                result += "\(label): \(child.value)"
            } else {
                result += "\(child.value)"
            }
        }
        return result
    }
}

(This is a generic solution that should be usable for many types, not just enums. You'll probably have to add some line breaks for types that have more than a single child.)


Edit 2: Mirror is also what print and String(describing:) use for types that don't conform to Custom[Debug]StringConvertible. You can check out the source code here.

like image 59
Ole Begemann Avatar answered Oct 20 '22 16:10

Ole Begemann