Having seen several posts about the desire for attributes in Swift and having the same desire myself, I thought I would play with implementing something with Swift as it is now.
public protocol Attribute { }
public protocol Attributable
{
static func getAttributes() -> [Attribute]
}
public struct Serializable : Attribute
{
public private(set) var targetType: Any.Type
public init(_ targetType: Any.Type)
{
self.targetType = targetType
}
}
public struct SerializableProperty : Attribute
{
public private(set) var keyPath: AnyKeyPath
public private(set) var isSerializable: Bool
public init(keyPath: AnyKeyPath, isSerializable: Bool = true)
{
self.keyPath = keyPath
self.isSerializable = isSerializable
}
}
public struct Person
{
public var firstName: String
public var lastName: String
public var fullname: String
{
return "\(firstName) \(lastName)"
}
}
extension Person : Attributable
{
public static func getAttributes() -> [Attribute]
{
return [
Serializable(Person.self),
SerializableProperty(keyPath: \Person.fullname, isSerializable: false)
]
}
}
Then, to recover the attributes elsewhere:
{
let testType: Any.Type = Person.self
if let attributableType = testType as? Attributable.Type
{
let attributes = attributableType.getAttributes()
for attribute in attributes
{
switch attribute
{
case let serializableType as Serializable:
print("\(serializableType.targetType)")
case let serializableProperty as SerializableProperty:
print("\(serializableProperty.isSerializable) : \(serializableProperty.keyPath)")
default:
print("default")
}
}
}
}