В моем коде я использую функцию расширения протокола, которая использует Mirror, чтобы получить соответствующее значение из перечисления. Это работает только для случаев, у которых нет метки для связанных значений, в то время как случаи, у которых есть метки для связанных значений, не работают.
Итак, вот протокол
public protocol Enumeration { }
/// Enum extension for getting the associated value of an enum
public extension Enumeration {
/// Get the associated value of the enum, this only works if the associated value does NOT have a label
public var associated: (label: String, value: Any?) {
let mirror = Mirror(reflecting: self)
if mirror.displayStyle == .enum {
if let associated = mirror.children.first, let key = associated.label {
return (key, associated.value)
}
print("WARNING: Enumeration option of \(self) does not have an associated value")
return ("\(self)", nil)
}
print("WARNING: You can only extend an enum with the Enumeration Extension")
return ("\(self)", nil)
}
}
А теперь вот мои юнит-тесты, которые я использую Quick кстати.
// пример enum
личное перечисление оружие: перечисление {
футляр для меча (String)
кейс кинжал (скорость: Int)
}
override func spec() {
it("should have access to associated value") {
let enchantment: String = "Fire Damage +10"
let sword: Weapon = .sword(enchantment)
XCTAssertEqual(sword.associated.label, "sword")
// ===============
// This works
// ===============
if let value = sword.associated.value as? String {
XCTAssertEqual(value, enchantment)
} else {
XCTFail("unable to unwrap assoicated value")
}
let speed: Int = 12
let dagger: Weapon = .dagger(speed: speed)
XCTAssertEqual(dagger.associated.label, "dagger")
// ===============
// This does not
// ===============
if let value = dagger.associated.value as? Int {
XCTAssertEqual(value, speed)
} else {
XCTFail("unable to unwrap associated value")
}
}
}