Skip to content

Instantly share code, notes, and snippets.

@andrewGarson
Last active May 5, 2019 00:05
Show Gist options
  • Save andrewGarson/560b86ebd08e7236858a8930e12aa0aa to your computer and use it in GitHub Desktop.
Save andrewGarson/560b86ebd08e7236858a8930e12aa0aa to your computer and use it in GitHub Desktop.
sourcery --sources Folder/Containing/Messages --templates Folder/Containing/Templates --output Folder/Containing/GeneratedSerializationExtensions
// Adopt this protocol to codegen an extension adopting Encodable inside a root key
protocol RestRequest {
static var RestRequestRootKey: String { get }
}
// Adopt this protocol to codegen an extension adopting Decodable inside a root key
protocol RestResponse {
static var RestResponseRootKey: String { get }
}
// MARK: SomeMessage Encodable
extension SomeMessage: Encodable {
private enum CodingKeys : String, CodingKey {
// Skipped Properties: ["skipMe", "skipMeToo"]
case root = "SomeMessageAsARequestEnvelope"
case id
case name
case enabled
}
public func encode(to encoder: Encoder) throws {
var root = encoder.container(keyedBy: CodingKeys.self)
var body = root.nestedContainer(keyedBy: CodingKeys.self, forKey: .root)
try body.encode(self.id, forKey: .id)
try body.encode(self.name, forKey: .name)
try body.encode(self.enabled, forKey: .enabled)
}
}
import Common
import DataModel
<% for type in types.implementing["RestRequest"] { -%>
// MARK: <%= type.name %> Encodable
extension <%= type.name %>: Encodable {
private enum CodingKeys : String, CodingKey {
<%
var skipKeys : [String] = []
if let skipEnum = type.containedTypes.first(where: { $0.localName == "RestRequestSkipKeys" }) as? Enum {
skipKeys = skipEnum.cases.map { $0.name }
}
let rootVariable = type.staticVariables.first { $0.name == "RestRequestRootKey" }!
let variablesToSerialize = type.storedVariables.filter({ variable in
!skipKeys.contains(where: { skipKey in
return variable.name == skipKey
})
})
-%>
// Skipped Properties: <%= skipKeys %>
case root = <%= rootVariable.defaultValue! %>
<% for v in variablesToSerialize { -%>
case <%=v.name%>
<% } -%>
}
public func encode(to encoder: Encoder) throws {
var root = encoder.container(keyedBy: CodingKeys.self)
var body = root.nestedContainer(keyedBy: CodingKeys.self, forKey: .root)
<% for v in variablesToSerialize { -%>
try body.encode(self.<%=v.name%>, forKey: .<%=v.name%>)
<% } -%>
}
}
<% } -%>
// MARK: SomeMessage Decodable
extension SomeMessage: Decodable {
private enum CodingKeys : String, CodingKey {
case root = "SomeMessageAsAResponseEnvelope"
case id
case name
case enabled
}
public init(from decoder:Decoder) throws {
let wrapper = try decoder.container(keyedBy: CodingKeys.self)
let body = try wrapper.nestedContainer(keyedBy: CodingKeys.self, forKey: .root)
try self.init(from: body)
}
private init(from container: KeyedDecodingContainer<CodingKeys>) throws {
self.id = try container.decode(Int.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
self.enabled = try container.decode(Bool.self, forKey: .enabled)
}
}
import Common
import DataModel
<% for type in types.implementing["RestResponse"] { -%>
// MARK: <%= type.name %> Decodable
extension <%= type.name %>: Decodable {
private enum CodingKeys : String, CodingKey {
<%
let rootVariable = type.staticVariables.first { $0.name == "RestResponseRootKey" }!
-%>
case root = <%= rootVariable.defaultValue! %>
<% for v in type.storedVariables { -%>
case <%=v.name%>
<% } -%>
}
public init(from decoder:Decoder) throws {
let wrapper = try decoder.container(keyedBy: CodingKeys.self)
let body = try wrapper.nestedContainer(keyedBy: CodingKeys.self, forKey: .root)
try self.init(from: body)
}
private init(from container: KeyedDecodingContainer<CodingKeys>) throws {
<% for v in type.storedVariables { -%>
self.<%=v.name%> = try container.decode(<%=v.typeName%>.self, forKey: .<%=v.name%>)
<% } -%>
}
}
<% } -%>
public struct SomeMessage : RestResponse, RestRequest {
static let RestResponseRootKey: String = "SomeMessageAsAResponseEnvelope"
static let RestRequestRootKey: String = "SomeMessageAsARequestEnvelope"
// Don't serialize these keys
enum RestRequestSkipKeys {
case skipMe
case skipMeToo
}
public var id: Int = -100
public var name: String = ""
public var enabled: Bool = false
public var skipMe: Int { get { return 0; } }
public var skipMeToo: Int { get { return 0; } }
//...the rest of your properties here
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment