Created
December 17, 2018 22:17
-
-
Save nathantannar4/97fc656889c4669bfb179b54bf88f24c to your computer and use it in GitHub Desktop.
Generate JSON representation of values using the Mirror API
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
// | |
// Reflectable.swift | |
// | |
// Created by Nathan Tannar on 2018-12-04. | |
// | |
import Foundation | |
// Add this protocol to your `struct` or `class` | |
protocol Reflectable { | |
func asJSON() -> Any? | |
} | |
// A RawValue `enum` can be reflected if it conforms to | |
protocol RawValueReflectable: Reflectable {} | |
extension Reflectable { | |
func asJSON() -> Any? { | |
let mirror = Mirror(reflecting: self) | |
guard mirror.children.count > 0 else { return self } | |
var out: [String: Any] = [:] | |
for case let (key?, value) in mirror.children { | |
if let value = value as? Reflectable { | |
out[key] = value.asJSON() | |
} | |
} | |
return out | |
} | |
} | |
extension String: Reflectable {} | |
extension Int: Reflectable {} | |
extension Float: Reflectable {} | |
extension Double: Reflectable {} | |
extension Bool: Reflectable {} | |
extension Array: Reflectable where Element: Reflectable { | |
func asJSON() -> Any? { | |
return compactMap { $0.asJSON() } | |
} | |
} | |
extension Optional: Reflectable where Wrapped: Reflectable { | |
func asJSON() -> Any? { | |
switch self { | |
case .some(let value): | |
return value.asJSON() | |
case .none: | |
return nil | |
} | |
} | |
} | |
extension Dictionary: Reflectable where Key == String, Value: Reflectable { | |
func asJSON() -> Any? { | |
return mapValues { $0.asJSON() ?? $0 } | |
} | |
} | |
extension RawValueReflectable where Self: RawRepresentable, Self.RawValue: Reflectable { | |
func asJSON() -> Any? { | |
return rawValue | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment