Create a gist now

Instantly share code, notes, and snippets.

An exploration of a possible KVC-like API for a future version of Swift.
/// A statically typed view into a get-only property.
struct TypedGetPropertyView<T> {
/// The name of the property, as a string.
let name : String
/// The actual metatype of the property.
let metatype : T.Type
/// Get the value of the property.
func get() -> T
/// Attempt to build a statically typed view from a dynamically typed view.
init?(propertyView: GetPropertyView)
}
/// A statically typed view into a get-set property.
struct TypedGetSetPropertyView<T> {
let name : String
let metatype : T.Type
func get() -> T
/// Set the property to a new value.
func set(newValue: T)
init?(propertyView: GetSetPropertyView)
/// If a get-only view corresponds to a get-set property, return a new
/// view that allows for getting and setting of the value.
init?(propertyView: TypedGetPropertyView<T>)
}
/// A dynamically typed view into a get-only property.
struct GetPropertyView {
let name : String
let metatype : Any.Type
func get() -> Any
/// Turn a statically typed view into a dynamic view.
init<T>(propertyView: GetPropertyView<T>)
}
/// A dynamically typed view into a get-set property.
struct GetSetPropertyView {
let name : String
let metatype : Any.Type
func get() -> Any
/// Attempt to set the property to a new value. Throws if a type error occurs.
func set(newValue: Any) throws
init<T>(propertyView: GetSetPropertyView<T>)
init?(propertyView: GetPropertyView<T>)
}
/// Either a statically typed get-only property, or a get-set property.
enum TypedPropertyView<T> {
case Get(TypedGetPropertyView<T>)
case GetSet(TypedGetSetPropertyView<T>)
var asGet : TypedGetPropertyView<T>?
var asGetSet : TypedGetSetPropertyView<T>?
}
/// Either a dynamically typed get-only property, or a get-set property.
enum PropertyView {
case Get(GetPropertyView)
case GetSet(GetSetPropertyView)
var asGet : GetPropertyView?
var asGetSet : GetSetPropertyView?
}
/// Conform a type to PropertyReflectable for the compiler to automatically generate
/// an interface for reflecting upon properties.
@magic protocol PropertyReflectable {
/// Returns an untyped view into a property with a given name, or nil if no property
/// with that name exists.
func property(name: String, searchSupertype: Bool = false) -> PropertyView?
/// Returns a get-only view into a property with a given name, or nil if no property
/// with that name exists.
func getOnlyProperty(name: String, searchSupertype: Bool = false) -> GetPropertyView?
/// Returns a get-set view into a property with a given name, or nil if the property
/// either doesn't exist or is a get-only property.
func getSetProperty(name: String, searchSupertype: Bool = false) -> GetSetPropertyView?
/// Returns a typed view into a property with a given name, or nil if no property
/// with the given name and type exists. If the property's type is a subtype of
/// the given type, a view into the property parameterized by the given type will
/// be returned.
func typedProperty<T>(name: String, searchSupertype: Bool = false) -> TypedPropertyView<T>?
/// Returns a typed get-only view into a property with a given name. Returns nil if no
/// property with the name exists or the type is incompatible.
func typedGetOnlyProperty<T>(name: String, searchSupertype: Bool = false) -> TypedGetPropertyView<T>?
/// Returns a typed get-set view into a property with a given name. Returns nil if no
/// property with the naame exists, the type is incompatible, or the property is get-only.
func typedGetSetProperty(name: String, searchSupertype: Bool = false) -> TypedGetSetPropertyView<T>?
/// Returns an array of untyped views into each of the properties defined on this
/// type.
func allProperties(includeSupertypeProperties: Bool = false) -> [PropertyView]
/// Returns a dictionary of untyped views into each of the properties defined on
/// this type. The keys are the property names; the values are the views.
func allNamedProperties(includeSupertypeProperties: Bool = false) -> [String : PropertyView]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment