Получение связанных значений через Зеркало не работает, если соответствующее значение имеет метку - PullRequest
0 голосов
/ 15 марта 2019

В моем коде я использую функцию расширения протокола, которая использует 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")
        }
    }
}
...