Skip to content

Instantly share code, notes, and snippets.

@V8tr
Created March 7, 2018 15:08
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 V8tr/ee02e6547c2fed478f9c6d3a93502df8 to your computer and use it in GitHub Desktop.
Save V8tr/ee02e6547c2fed478f9c6d3a93502df8 to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
protocol JSONSerializable {
func toJSON() throws -> Any?
}
enum CouldNotSerializeError: Error {
case noImplementation(source: Any, type: String)
}
extension JSONSerializable {
func toJSON() throws -> Any? {
let mirror = Mirror(reflecting: self)
guard !mirror.children.isEmpty else { return self }
var result: [String: Any] = [:]
for child in mirror.children {
if let value = child.value as? JSONSerializable {
result[child.label!] = try value.toJSON()
} else {
throw CouldNotSerializeError.noImplementation(source: self, type: String(describing: type(of: child.value)))
}
}
return result
}
}
struct Order {
let uid = UUID()
let itemsCount = 1
let isDeleted = false
let name = "A cup"
let subtitle: String? = nil
let category = Category(name: "Cups")
}
struct Category {
let name: String
}
extension String: JSONSerializable {}
extension Int: JSONSerializable {}
extension Bool: JSONSerializable {}
extension Optional: JSONSerializable {
func toJSON() throws -> Any? {
if let x = self {
if let value = x as? JSONSerializable {
return try value.toJSON()
}
throw CouldNotSerializeError.noImplementation(source: x, type: String(describing: type(of: x)))
}
return nil
}
}
extension UUID: JSONSerializable {
func toJSON() throws -> Any? {
return try uuidString.toJSON()
}
}
extension Order: JSONSerializable {}
extension Category: JSONSerializable {}
do {
try Order().toJSON()
} catch {
print(error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment