Last active
January 24, 2021 07:28
-
-
Save V8tr/3ab9ab1a550415fae5d61aa39d3a2185 to your computer and use it in GitHub Desktop.
Sample code for my blog post Reflection and Mirror in Swift http://www.vadimbulavin.com/2018-03-09-reflection-and-mirror-in-swift/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
protocol JSONSerializable { | |
func toJSON() throws -> Any? | |
} | |
enum CouldNotSerializeError: Error { | |
case noImplementation(source: Any, type: String) | |
case undefinedKey(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 { | |
if let key = child.label { | |
result[key] = try value.toJSON() | |
} else { | |
throw CouldNotSerializeError.undefinedKey(source: self, type: String(describing: type(of: child.value))) | |
} | |
} 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 UUID: JSONSerializable {} | |
extension Order: JSONSerializable {} | |
extension Category: JSONSerializable {} | |
extension Optional: JSONSerializable { | |
func toJSON() throws -> Any? { | |
if let x = self { | |
guard let value = x as? JSONSerializable else { | |
throw CouldNotSerializeError.noImplementation(source: x, type: String(describing: type(of: x))) | |
} | |
return try value.toJSON() | |
} | |
return nil | |
} | |
} | |
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