Skip to content

Instantly share code, notes, and snippets.

@bocato
Last active September 12, 2022 08:01
Show Gist options
  • Save bocato/f26176a8727b8a6d574ef95a5841a5f0 to your computer and use it in GitHub Desktop.
Save bocato/f26176a8727b8a6d574ef95a5841a5f0 to your computer and use it in GitHub Desktop.
Unwrapping erased values
import Foundation
protocol ErasedType {
var erasedValue: Any { get }
}
extension ErasedType {
func recursivelyUnwrap<T>(as type: T.Type) -> T? {
return recrusivelyUnwrapErasedType(
value: erasedValue,
originalType: T.self,
erasedType: Self.self
)
}
}
func recrusivelyUnwrapErasedType<Original, Erased: ErasedType>(
value: Any,
originalType: Original.Type,
erasedType: Erased.Type
) -> Original? {
if let boxedValue = value as? Erased {
print("Got ERASED value!")
return recrusivelyUnwrapErasedType(
value: boxedValue.erasedValue,
originalType: Original.self,
erasedType: Erased.self
)
} else {
print("Got REAL value!")
return value as? Original
}
}
// testing this
protocol ThingProtocol {
associatedtype ValueType
var value: ValueType { get }
}
struct StringThing: ThingProtocol {
var value: String
}
struct AnyThing: ThingProtocol, ErasedType {
var value: Void { fatalError() }
let erasedValue: Any
init<T: ThingProtocol>(erasing value: T) {
self.erasedValue = value
}
func unwrap<T>(as: T.Type) -> T? {
return recursivelyUnwrap(as: T.self)
}
}
let anyThing: AnyThing = .init(
erasing: AnyThing(
erasing: AnyThing(
erasing: StringThing(value: "Hey!")
)
)
)
// print(anyThing)
// let realValue = recrusivelyUnwrapErasedType(
// value: anyThing,
// originalType: StringThing.self,
// erasedType: AnyThing.self
// )
// print("RealValue = \(realValue)")
// let realValue = anyThing.unwrap(as: StringThing.self)
// print("RealValue = \(realValue)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment