Skip to content

Instantly share code, notes, and snippets.

@vzsg
Last active December 30, 2017 00:48
Show Gist options
  • Save vzsg/4219062f86668ad61292b3a67c797747 to your computer and use it in GitHub Desktop.
Save vzsg/4219062f86668ad61292b3a67c797747 to your computer and use it in GitHub Desktop.
StructuredData + Codable = win?
import Foundation
import Vapor
private enum UniversalCodingKey: CodingKey {
case int(Int)
case string(String)
init?(intValue: Int) {
self = .int(intValue)
}
init?(stringValue: String) {
self = .string(stringValue)
}
var intValue: Int? {
guard case .int(let intValue) = self else {
return nil
}
return intValue
}
var stringValue: String {
switch self {
case .string(let string):
return string
case .int(let int):
return int.description
}
}
}
extension StructuredData: Encodable {
public func encode(to encoder: Encoder) throws {
switch self {
case .array(let array):
var container = encoder.unkeyedContainer()
try container.encode(contentsOf: array)
case .bool(let bool):
var container = encoder.singleValueContainer()
try container.encode(bool)
case .bytes(let bytes):
var container = encoder.singleValueContainer()
try container.encode(Data(bytes))
case .date(let date):
var container = encoder.singleValueContainer()
try container.encode(date)
case .null:
var container = encoder.singleValueContainer()
try container.encodeNil()
case .number(let number):
var container = encoder.singleValueContainer()
switch number {
case .double(let double):
try container.encode(double)
case .int(let int):
try container.encode(int)
case .uint(let uint):
try container.encode(uint)
}
case .object(let object):
var container = encoder.container(keyedBy: UniversalCodingKey.self)
try object.forEach {
try container.encode($1, forKey: UniversalCodingKey.string($0))
}
case .string(let string):
var container = encoder.singleValueContainer()
try container.encode(string)
}
}
}
// TODO: if the plan works and StructuredDataWrapper can conform to Encodable,
// these separate extensions will not be needed at all!
extension Node: Encodable {
public func encode(to encoder: Encoder) throws {
try wrapped.encode(to: encoder)
}
}
extension Row: Encodable {
public func encode(to encoder: Encoder) throws {
try wrapped.encode(to: encoder)
}
}
extension JSON: Encodable {
public func encode(to encoder: Encoder) throws {
try wrapped.encode(to: encoder)
}
}
extension Identifier: Encodable {
public func encode(to encoder: Encoder) throws {
try wrapped.encode(to: encoder)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment