👔CaseReflectable
💾 程式:paiza.io ⬆️ 需要: Mirror, HasMirrors
// --------------------------
// ⭐ CaseReflectable
// --------------------------
// designed for enums only (use it on other types not recommended)
public protocol CaseReflectable: Loggable {
/// log enum case (default implementation provided)
func logEnumCase() -> Self
}
// ⭐ default behavior.
extension CaseReflectable {
/// ⭐ case name
public var caseName: String {
let mirror = Mirror(reflecting: self)
// enum cases:
// - normal case: no children
// - case with associated values: one child (with label)
guard let label = mirror.children.first?.label else {
return "\(self)" // normal case
}
// ase with associated values
return label
}
/// ⭐ associated values
public var associatedValues: Any? {
// if no children, a normal case, no associated values.
guard let firstChild = Mirror(reflecting: self).children.first else {
return nil
}
// return associated values
return firstChild.value
}
/// ⭐ log enum case
@discardableResult
public func logEnumCase() -> Self {
if let values = self.associatedValues {
print("case: .\(caseName), values: \(values), type: \(type(of: values))")
} else {
print("case: .\(caseName) (no associated values)")
}
return self
}
}
// -----------------------------
// ⭐ custom operator ~=
// -----------------------------
/// match enum cases with associated values, while disregarding the values themselves.
/// usage: `Enum.enumCase ~= instance`
public func ~= <Enum: CaseReflectable, AssociatedValue>(
// an enum case (with associated values)
enumCase: (AssociatedValue) -> Enum, // enum case as function
// an instance of Enum
instance: Enum
) -> Bool
{
// if no associated values, `instance` can't be of `enumCase`
guard let values = instance.associatedValues else { return false }
// if associated values not of the same type, return false
guard values is AssociatedValue else { return false }
// create an instance from `enumCase` (as function)
let case2 = enumCase(values as! AssociatedValue)
// if same case name, return true
return case2.caseName == instance.caseName
}
Last updated
Was this helpful?