Skip to content

Instantly share code, notes, and snippets.

@brianmichel
Created March 2, 2024 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianmichel/71c463acba7382d3c929803d1bf49a7a to your computer and use it in GitHub Desktop.
Save brianmichel/71c463acba7382d3c929803d1bf49a7a to your computer and use it in GitHub Desktop.
Code that tries to reconstruct WritableKeyPaths from AnyKeyPath using _openExistential
Original WritableKeyPath is \MyFeatureFlags.fontOptions
Got specialization: CaseIterable
Reconstructed WritableKeyPath is \MyFeatureFlags.fontOptions
Got specialization: Base
import Foundation
enum FontOptions: String, RawRepresentable, CaseIterable {
case system
case chalkdust
}
struct MyFeatureFlags {
var flagInt: Int = 1
var flagOne: Bool = true
var fontOptions: FontOptions = .system
var flagString: String = "huh"
}
struct FlagContainer {
var flags = MyFeatureFlags()
}
func specialized<R, V>(value: WritableKeyPath<R, V>) -> String {
"Base"
}
func specialized<R>(value: WritableKeyPath<R, Bool>) -> String {
"Bool"
}
func specialized<R>(value: WritableKeyPath<R, String>) -> String {
"String"
}
func specialized<R, V>(value: WritableKeyPath<R, V>) -> String where V: CaseIterable, V: RawRepresentable, V.RawValue == String {
"CaseIterable"
}
func reconstructWritableKeyPath(from kp: AnyKeyPath) {
let rootType = type(of: kp).rootType
let valueType = type(of: kp).valueType
func outer<Root>(_: Root.Type) {
func inner<Value>(_: Value.Type) {
let path = kp as! WritableKeyPath<Root, Value>
print("Reconstructed WritableKeyPath is \(path)")
print("Got specialization: \(specialized(value: path))")
}
_openExistential(valueType, do: inner)
}
_openExistential(rootType, do: outer)
}
let container = FlagContainer()
let keypath = \MyFeatureFlags.fontOptions
let anyKeypath = keypath as AnyKeyPath
print("Original WritableKeyPath is \(keypath)")
print("Got specialization: \(specialized(value: keypath))\n")
reconstructWritableKeyPath(from: anyKeypath)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment