1

so I have a function which receives an Any and it checks if the Any is an enum by using reflection:

func extractRawValue(subject: Any) throws -> Any {
    let mirror = Mirror(reflecting: subject)

    guard let displayStyle = mirror.displayStyle,
        case .`enum` = displayStyle else {
            throw Errors.NoEnum
    }

    // And from here I don't know how to go any further...
    // I wish I could do something like this:
    guard let subject = subject as? RawRepresentable where let rawValue = subject.rawValue as Any else {
        throw Errors.NoRawRepresenable
    }

    return rawValue 
}

Does anyone know how I can accomplish something like that?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Evert
  • 2,022
  • 1
  • 20
  • 29
  • What question is `guard let subject = subject as? RawRepresentable where let rawValue = subject.rawValue as Any` trying to ask? I see that the first part asks whether this thing _is_ a RawRepresentable, but I cannot imagine what the second part is even supposed to mean. Help me out here. – matt Nov 10 '16 at 19:47
  • Did you succeed? I'm trying to find out something similar here: http://stackoverflow.com/questions/43666118/if-let-any-to-rawrepresentablestring – Dannie P Apr 27 '17 at 20:36

1 Answers1

2

I think the Swifty way to do this is to use a protocol for the enums you want to use:

protocol ValueAsAnyable {
    func valueAsAny() -> Any
}

extension ValueAsAnyable where Self: RawRepresentable {
    func valueAsAny() -> Any {
        return rawValue as Any
    }
}

func extractRawValue(subject: Any) throws -> Any {
    let mirror = Mirror(reflecting: subject)

    guard let displayStyle = mirror.displayStyle,
        case .`enum` = displayStyle else {
            throw Errors.NoEnum
    }
    guard let anyable = subject as? ValueAsAnyable else {
        throw Errors.NoRawRepresentable
    }
    return anyable.valueAsAny()
}

let subject: Any = TestEnum.test
let thing = try? extractRawValue(subject: subject) //prints "test"

This should allow you to do what you need, but keep Type safety.

GetSwifty
  • 7,568
  • 1
  • 29
  • 46
  • 1
    Ah yes, I forgot to say, but the whole point was to not have to do that. – Evert Nov 10 '16 at 21:15
  • I added an extension that will automatically implement it so it's simply adding it to your enum declaration. AFAIK that's as close as you can get until Swift adds more dynamism or better reflection. – GetSwifty Nov 10 '16 at 21:48