Skip to content

Instantly share code, notes, and snippets.

@dreymonde
Created May 23, 2016 17:55
Show Gist options
  • Save dreymonde/48f35ca1461213edf76697e30d2ee1bd to your computer and use it in GitHub Desktop.
Save dreymonde/48f35ca1461213edf76697e30d2ee1bd to your computer and use it in GitHub Desktop.
public protocol Structure {
static var arrayLiteral: ([Self]) -> Self { get }
}
public protocol IntSupportingStructure {
static var fromInt: (Int) -> Self { get }
static var toInt: (Self) -> Int? { get }
}
public enum JSON {
public enum Number {
case integer(Int)
case unsignedInteger(UInt)
case double(Double)
}
case object([String: JSON])
case array([JSON])
case number(JSON.Number)
case string(String)
case boolean(Bool)
case null
}
extension JSON: IntSupportingStructure {
public static var fromInt: (Int) -> JSON {
return { JSON.number(.integer($0)) }
}
public static var toInt: (JSON) -> Int? {
return {
if case let .number(number) = $0, case let .integer(int) = number {
return int
}
return nil
}
}
}
public enum MyStructure {
case integer(Int)
case string(String)
case array([MyStructure])
case dictionary([String: MyStructure])
}
extension MyStructure: Structure, IntSupportingStructure {
public static var arrayLiteral: ([MyStructure]) -> MyStructure {
return MyStructure.array
}
public static var fromInt: (Int) -> MyStructure {
return MyStructure.integer
}
public static var toInt: (MyStructure) -> Int? {
return {
if case let .integer(int) = $0 {
return int
}
return nil
}
}
}
// This is super useful for automatically bridgint arrays
let structs: [MyStructure] = [.integer(5), .string("5"), .integer(10)]
let structi = MyStructure.arrayLiteral(structs)
func convert<From: IntSupportingStructure, To: IntSupportingStructure>(_ inside: From) -> To? {
return inside.dynamicType.toInt(inside).map({ To.fromInt($0) })
}
let intJson = JSON.number(.integer(10))
let intMy: MyStructure? = convert(intJson)
print(intMy)
// This works!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment